比方说,我已经添加在UIStackView多个视图可以显示的,我怎么能做出UIStackView
卷轴?
如果有人正在寻找无代码的解决方案,我创建了一个例子,在故事板完全做到这一点,使用自动布局。
您可以从github得到它。
基本上,以重新创建例如:
UIScrollView
,并设置其限制。UIStackView
添加到UIScrollView
Leading
,Trailing
,Top
&Bottom
应该等于从UIScrollView
的那些Width
和UIStackView
之间的平等UIScrollView
约束。UIStackView
UIViews
到UIStackView
如果你有一个约束垂直居中滚动视图中的堆栈视图中,只是将其删除。
例如,对于一个垂直stackview /滚动视图(使用自动布局的@import ScrollableStackView
ScrollableStackView *scrollable = [[ScrollableStackView alloc] initWithFrame:self.view.frame];
scrollable.stackView.distribution = UIStackViewDistributionFillProportionally;
scrollable.stackView.alignment = UIStackViewAlignmentCenter;
scrollable.stackView.axis = UILayoutConstraintAxisVertical;
[self.view addSubview:scrollable];
UIView *rectangle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 55)];
[rectangle setBackgroundColor:[UIColor blueColor]];
// add your views with
[scrollable.stackView addArrangedSubview:rectangle];
// ...
):
EasyPeasy
只要确保每个子视图的高度的定义!
虽然与堆栈视图工作
让您的观点后,把母亲堆栈视图和滚动视图之间的约束,而约束孩子堆栈视图与母亲堆栈视图。希望通过这次它应该可以正常工作,或者你可能会从Xcode的建议给予警告,念出来并实施这些。希望现在你应该有一个工作视图按照您的期望:)。
对于嵌套或单个堆栈视图滚动视图必须设置与根视图一个固定的宽度。这是滚动视图的内部主视图堆必须设置相同的宽度。 [我的滚动视图是波纹管观的忽略它]
建立UIStackView和UIScrollView中之间的相等宽度约束。
let scrollView = UIScrollView()
self.view.addSubview(scrollView)
scrollView <- [
Edges(),
Width().like(self.view)
]
let stackView = UIStackView(arrangedSubviews: yourSubviews)
stackView.axis = .vertical
stackView.distribution = .fill
stackView.spacing = 10
scrollView.addSubview(stackView)
stackView <- [
Edges(),
Width().like(self.view)
]
放置在场景滚动视图,所以它填充场景大小了。然后,将滚动视图内的堆栈视图,并将其放置在堆栈视图内的添加项目按钮。只要一切都在的地方,设置以下限制:
func createHorizontalStackViewsWithScroll() {
self.view.addSubview(stackScrollView)
stackScrollView.translatesAutoresizingMaskIntoConstraints = false
stackScrollView.heightAnchor.constraint(equalToConstant: 85).isActive = true
stackScrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
stackScrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
stackScrollView.bottomAnchor.constraint(equalTo: visualEffectViews.topAnchor).isActive = true
stackScrollView.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.topAnchor.constraint(equalTo: stackScrollView.topAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: stackScrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: stackScrollView.trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: stackScrollView.bottomAnchor).isActive = true
stackView.heightAnchor.constraint(equalTo: stackScrollView.heightAnchor).isActive = true
stackView.distribution = .equalSpacing
stackView.spacing = 5
stackView.axis = .horizontal
stackView.alignment = .fill
for i in 0 ..< images.count {
let photoView = UIButton.init(frame: CGRect(x: 0, y: 0, width: 85, height: 85))
// set button image
photoView.translatesAutoresizingMaskIntoConstraints = false
photoView.heightAnchor.constraint(equalToConstant: photoView.frame.height).isActive = true
photoView.widthAnchor.constraint(equalToConstant: photoView.frame.width).isActive = true
stackView.addArrangedSubview(photoView)
}
stackView.setNeedsLayout()
}
Scroll View.Leading = Superview.LeadingMargin
Scroll View.Trailing = Superview.TrailingMargin
Scroll View.Top = Superview.TopMargin
Bottom Layout Guide.Top = Scroll View.Bottom + 20.0
Stack View.Leading = Scroll View.Leading
Stack View.Trailing = Scroll View.Trailing
Stack View.Top = Scroll View.Top
Stack View.Bottom = Scroll View.Bottom
Stack View.Width = Scroll View.Width
把它变成一个Stack View.Width = Scroll View.Width
...
苹果公司的自动布局指南包括对Working with Scroll Views一整节。一些相关的片段:
- 针内容视图的顶部,底部,导致,和后缘滚动视图的相应的边缘。内容视图现在定义滚动视图的内容区域。
- (可选的)要禁用水平滚动,设定为等于滚动视图的宽度的内容视图的宽度。内容视图现在水平充满滚动视图。
- (可选的)要禁用垂直滚动,设置内容视图的高度等于滚动视图的高度。内容视图现在水平充满滚动视图。
此外:
您的布局必须完全定义的内容视图的大小(除非在步骤5和6所定义的)。 ...当含量视图比滚动视图高,滚动视图使垂直滚动。当该含量视图比滚动视图更宽,滚动视图使水平滚动。
总之,滚动视图的内容视图(在这种情况下,堆叠视图)必须被固定到它的边缘和具有其宽度和/或高度另有限制。这意味着,堆栈视图的内容必须可以在其滚动期望的方向(S),这可能意味着增加了高度约束到每个视图中的垂直滚动堆栈视图内部,例如(直接或间接)的限制。以下是如何允许用于容纳堆叠视图滚动视图的垂直滚动的例子:
// Pin the edges of the stack view to the edges of the scroll view that contains it
stackView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor).active = true
stackView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor).active = true
stackView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor).active = true
// Set the width of the stack view to the width of the scroll view for vertical scrolling
stackView.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true
作为EIK说,UIStackView
和UIScrollView
很好地一起玩,看到here。
关键是,UIStackView
处理可变高度/宽度不同的内容,然后UIScrollView
做滚动/弹跳该内容的分内的工作:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSize(width: stackView.frame.width, height: stackView.frame.height)
}
在得票最多的答案约束在这里工作对我来说,我已经粘贴了以下限制的图像,在我的故事板创建。
我也打不过别人应该注意的两个问题:
Need constraints for: X position or width
。这通过将一个UILabel作为堆栈视图的子视图解决。
我编程添加子视图,所以我本来就没有故事板子视图。为了摆脱自动版式错误的,一个子视图添加到故事板,然后将其删除在负荷增加你的真实的子视图和约束之前。UIButtons
添加到UIStackView。按钮和意见将加载,但滚动视图不会滚动。这通过将UILabels
到堆栈视图,而不是按钮解决。使用相同的限制,这种观点与UILabels滚动,但UIButtons层次没有。
我很困惑这个问题,因为UIButtons似乎有一个IntrinsicContentSize(由堆栈视图中使用)。如果有人知道为什么按钮不起作用,我很想知道为什么。这是我的看法层次和约束,以供参考:
我一直在寻找做同样的事情,偶然发现了这excellent post.如果你想这样做编程方式使用锚API,这是要走的路。
总之,嵌入您的UIStackView
在UIScrollView
,并设置UIStackView
的锚约束以匹配UIScrollView
的:
stackView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor).active = true
stackView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor).active = true
stackView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor).active = true
stackView.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true
只需添加这viewdidload
:
let insets = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0)
scrollVIew.contentInset = insets
scrollVIew.scrollIndicatorInsets = insets
对于水平滚动。首先,创建一个UIStackView
和UIScrollView
并将它们添加到下面的方式您的看法:
let scrollView = UIScrollView()
let stackView = UIStackView()
scrollView.addSubview(stackView)
view.addSubview(scrollView)
记住设置translatesAutoresizingMaskIntoConstraints
到false
在UIStackView
和UIScrollView
:
stackView.translatesAutoresizingMaskIntoConstraints = false
scrollView.translatesAutoresizingMaskIntoConstraints = false
为了让一切工作的尾部,导致的UIStackView
的顶部和底部锚应该等于UIScrollView
锚:
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
但UIStackView
必须比UIScrollView
锚的宽度等于或大于宽度锚:
stackView.widthAnchor.constraint(greaterThanOrEqualTo: scrollView.widthAnchor).isActive = true
现在,你的锚UIScrollView
,例如:
scrollView.heightAnchor.constraint(equalToConstant: 80).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo:view.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo:view.trailingAnchor).isActive = true
接下来,我会建议试图为UIStackView
对齐和分布如下设置:
topicStackView.axis = .horizontal
topicStackView.distribution = .equalCentering
topicStackView.alignment = .center
topicStackView.spacing = 10
最后,你需要使用addArrangedSubview:
方法子视图添加到您的UIStackView。
有一个附加功能,你可能会发现有用的是,由于UIStackView
是UIScrollView
内举行,你现在可以使用文字的插图使事情看起来有点漂亮。
let inset:CGFloat = 20
scrollView.contentInset.left = inset
scrollView.contentInset.right = inset
// remember if you're using insets then reduce the width of your stack view to match
stackView.widthAnchor.constraint(greaterThanOrEqualTo: topicScrollView.widthAnchor, constant: -inset*2).isActive = true
为了清楚起见,使背景颜色为红色;高度设置为100,并在堆叠视图中的间距设定为20。
UILabel
滚动视图,不堆栈视图,并选择相等的宽度。重复:
就这么简单。这是秘密。
你完成了。就这么简单。
提示:尝试添加一个新的项目,以堆栈视图,比方说,一个UIView(似乎可以作为的空间)。请注意,事事不顺心。事实上,你必须高度添加到每个新的项目(比如,“100”)。每次添加一个新项目的时候,你必须以某种方式给它的高度。
另一种方式来看待它:
在上述结构中,这样说:令人惊讶地,设置UILabels的宽度滚动视图(未堆栈视图)的宽度。完美的作品。
交替...
需要注意的是堆栈观点左右固定到其父,滚动视图。尝试这个:
所以,你有两个选择:
要么
需要明确的是,做这些方法之一,不要一举两得。
您可以尝试滚动StackView:qazxsw POI
这是Objective-C和斯威夫特兼容库。这可通过https://github.com/gurhub/ScrollableStackView。
示例代码(SWIFT)
CocoaPods
示例代码(Objective-C的)
import ScrollableStackView
var scrollable = ScrollableStackView(frame: view.frame)
view.addSubview(scrollable)
// add your views with
let rectangle = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 55))
rectangle.backgroundColor = UIColor.blue
scrollable.stackView.addArrangedSubview(rectangle)
// ...