its*_*ode 174 uiscrollview ios uistackview
假设我在UIStackView中添加了更多可以显示的视图,如何制作UIStackView
滚动?
Arj*_*jan 503
如果有人在寻找没有代码的解决方案,我创建了一个示例,使用自动布局在故事板中完全执行此操作.
你可以从github得到它.
基本上,要重新创建示例:
UIScrollView
,并设置其约束.UIStackView
到UIScrollView
Leading
,Trailing
,Top
和Bottom
应该等于从那些UIScrollView
Width
在UIStackView
和之间设置一个相等的约束UIScrollView
.UIStackView
UIViews
的UIStackView
tit*_*coy 41
Apple的"自动布局指南"包含有关使用滚动视图的整个部分.一些相关的片段:
- 将内容视图的顶部,底部,前导和尾部边缘固定到滚动视图的相应边缘.内容视图现在定义滚动视图的内容区域.
- (可选)要禁用水平滚动,请将内容视图的宽度设置为等于滚动视图的宽度.内容视图现在水平填充滚动视图.
- (可选)要禁用垂直滚动,请将内容视图的高度设置为等于滚动视图的高度.内容视图现在水平填充滚动视图.
此外:
您的布局必须完全定义内容视图的大小(步骤5和6中定义的除外)....当内容视图高于滚动视图时,滚动视图启用垂直滚动.当内容视图比滚动视图宽时,滚动视图启用水平滚动.
总而言之,滚动视图的内容视图(在这种情况下是堆栈视图)必须固定到其边缘,并且其宽度和/或高度另外受限制.这意味着必须在期望滚动的方向上(直接或间接)约束堆栈视图的内容,这可能意味着例如向垂直滚动堆栈视图内的每个视图添加高度约束.以下是如何允许垂直滚动包含堆栈视图的滚动视图的示例:
// 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
Run Code Online (Sandbox Code Playgroud)
小智 33
我向您展示正确的解决方案
对于 Xcode 11+
第 1 步: 添加ScrollView并调整其大小
第 2 步:为 ScrollView 添加约束
第三步:在 ScrollView 中 添加一个StackView,并调整它的大小。
第 4 步: 为 StackView 添加约束(Stask View -> Content Layout Guide -> "Leading, Top, Trailing, Bottom")
步骤 4.1: 正确的约束 ->常量(... -> 常量 = 0)
第 5 步: 为 StackView 添加约束(Stask View -> Frame Layout Guide -> "Equal Widths ")
步骤 6 示例:
添加两个带有HeightConstraints和RUN 的UIView(s)
我希望它对你有用
pka*_*amb 14
最高投票答案中的约束对我有用,并且我在我的故事板中创建了粘贴下面约束的图像.
虽然其他人应该知道,我确实遇到了两个问题:
添加类似于接受的答案中的约束后,我会得到红色自动布局错误Need constraints for: X position or width
.这是通过添加UILabel作为堆栈视图的子视图来解决的.
我正在以编程方式添加子视图,所以我最初在故事板上没有子视图.要消除自动布局错误,请在故事板中添加子视图,然后在添加真实子视图和约束之前将其删除.
我原本试图添加UIButtons
到UIStackView.按钮和视图将加载,但滚动视图不会滚动.这是通过添加UILabels
到堆栈视图而不是按钮来解决的.使用相同的约束,此视图层次结构与UILabels滚动但UIButtons不滚动.
我很困惑这个问题,因为UIButtons 都似乎有一个IntrinsicContentSize(由堆栈视图中使用).如果有人知道为什么按钮不起作用,我很想知道为什么.
这是我的视图层次结构和约束,供参考:
小智 13
正如Eik所说,UIStackView和UIScrollView很好地协同工作,请看这里.
关键是UIStackView处理不同内容的可变高度/宽度,然后UIScrollView可以很好地滚动/弹出该内容:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSize(width: stackView.frame.width, height: stackView.frame.height)
}
Run Code Online (Sandbox Code Playgroud)
我本来想做同样的事情,偶然发现了这篇优秀的帖子.如果您想使用锚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
Run Code Online (Sandbox Code Playgroud)
全屏空白
添加滚动视图。按住Control键从滚动视图拖动到基本视图,然后将left-right-top-bottom添加为零。
在滚动视图中添加一个堆栈视图。按住Control键从堆栈视图拖动到滚动视图,将left-right-top-bottom添加为零。
将一个UILabel放入堆栈视图中。
为了清楚起见,请将背景色设为红色;将高度设置为100,并在堆栈视图中将间距设置为20。
现在设置UILabel的宽度:
令人惊讶的是,按住Control键从拖动UILabel
到滚动视图,而不是堆栈视图,然后选择相等的宽度。
重复:
就这么简单。那是秘密。
你完成了。就这么简单。
提示:尝试向堆栈视图添加一个新项,例如UIView(可能用作空间)。请注意,一切都会出错。实际上,您必须为每个新项目添加一个高度(例如“ 100”)。每次添加新项目时,都必须以某种方式给它一个高度。
另一种查看方式:
在上面,它是这样说的:令人惊讶的是,将UILabels的宽度设置为滚动视图(而不是堆栈视图)的宽度。那很好。
交替...
请注意,堆栈视图的左侧和右侧固定到其父级(滚动视图)。尝试这个:
因此,您有两种选择:
要么
为了清楚起见,请选择其中一种方法,不要同时使用。
只需将其添加到viewdidload
:
let insets = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0)
scrollVIew.contentInset = insets
scrollVIew.scrollIndicatorInsets = insets
Run Code Online (Sandbox Code Playgroud)
来源:https: //developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html
用于水平滚动。首先,创建一个UIStackView
和一个UIScrollView
,然后通过以下方式将它们添加到您的视图中:
let scrollView = UIScrollView()
let stackView = UIStackView()
scrollView.addSubview(stackView)
view.addSubview(scrollView)
Run Code Online (Sandbox Code Playgroud)
记住设置translatesAutoresizingMaskIntoConstraints
,以false
在UIStackView
和UIScrollView
:
stackView.translatesAutoresizingMaskIntoConstraints = false
scrollView.translatesAutoresizingMaskIntoConstraints = false
Run Code Online (Sandbox Code Playgroud)
为了使一切正常,的尾随,前导,顶部和底部锚点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
Run Code Online (Sandbox Code Playgroud)
但是的宽度锚UIStackView
必须等于或大于UIScrollView
锚的宽度:
stackView.widthAnchor.constraint(greaterThanOrEqualTo: scrollView.widthAnchor).isActive = true
Run Code Online (Sandbox Code Playgroud)
现在锚定您的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
Run Code Online (Sandbox Code Playgroud)
接下来,建议对UIStackView
对齐和分布尝试以下设置:
topicStackView.axis = .horizontal
topicStackView.distribution = .equalCentering
topicStackView.alignment = .center
topicStackView.spacing = 10
Run Code Online (Sandbox Code Playgroud)
最后,您需要使用该addArrangedSubview:
方法将子视图添加到UIStackView中。
您可能会发现有用的另一个功能是,由于该UIStackView
功能保存在a中,因此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
Run Code Online (Sandbox Code Playgroud)