假设我在UIStackView中添加了更多可以显示的视图,我如何让UIStackView滚动?
当前回答
苹果的自动布局指南包括了一个关于使用滚动视图的完整部分。一些相关片段:
Pin the content view’s top, bottom, leading, and trailing edges to the scroll view’s corresponding edges. The content view now defines the scroll view’s content area. (Optional) To disable horizontal scrolling, set the content view’s width equal to the scroll view’s width. The content view now fills the scroll view horizontally. (Optional) To disable vertical scrolling, set the content view’s height equal to the scroll view’s height. The content view now fills the scroll view horizontally.
此外:
你的布局必须完全定义内容视图的大小(除了 . ...当内容视图比滚动视图高时,滚动视图允许垂直滚动。当内容视图比滚动视图宽时,滚动视图启用水平滚动。
To summarize, the scroll view's content view (in this case, a stack view) must be pinned to its edges and have its width and/or height otherwise constrained. That means that the contents of the stack view must be constrained (directly or indirectly) in the direction(s) in which scrolling is desired, which might mean adding a height constraint to each view inside a vertically scrolling stack view, for example. The following is an example of how to allow for vertical scrolling of a scroll view containing a stack view:
// Pin the edges of the stack view to the edges of the scroll view that contains it
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
// Set the width of the stack view to the width of the scroll view for vertical scrolling
stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
其他回答
在我的例子中,stackView内的视图数量是可变的,我想将项目居中。例如,在stackView中有一个视图,我希望这个视图位于屏幕中央,如果所有的视图都不适合屏幕,我希望视图是可滚动的。
这是我的视图的层次结构。
所以我为按钮设置了一个固定的宽度,然后,为stackView:
与按钮相同的固定宽度,但优先级为650。 对齐X中心到containerView 尾随>= 0和前导>= 0到containerView 底部和顶部空间到containerView
对于containerView:
拖尾,领先,底部,顶部,等高,等宽(250优先级)到superview 固定的高度
对于scrollView:
尾随,领先,底部,顶部到父视图
scrollView也嵌入到具有前导和后导约束的视图中。
关于我用来解决这个问题的代码:
for index in 0...array.count - 1 {
if index == 0 {
firstButton.setTitle(title, for: .normal)
} else {
let button = UIButton()
button.setTitle(title, for: .normal)
stackView.addArrangedSubview(button)
stackView.setNeedsLayout()
}
}
containerView.layoutIfNeeded()
stackView.distribution = .fillEqually
stackView.spacing = 10
stackView.alignment = .fill
如果有人正在寻找一个没有代码的解决方案,我创建了一个例子来完成这完全在故事板,使用自动布局。
你可以从github上得到。
基本上,要重新创建这个示例(用于垂直滚动):
创建一个UIScrollView,并设置它的约束。 添加一个UIStackView到UIScrollView 设置约束:前导,后尾,顶部和底部应该等于UIScrollView中的约束 在UIStackView和UIScrollView之间设置一个等宽约束。 在UIStackView上设置轴=垂直,对齐=填充,分布=等间距,间距= 0 添加一些uiview到UIStackView 运行
在第4步中将宽度交换为高度,并在第5步中设置轴=水平,以获得水平的UIStackView。
只需将这个添加到viewdidload:
let insets = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0)
scrollVIew.contentInset = insets
scrollVIew.scrollIndicatorInsets = insets
来源: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html
到2020年为止。
100%故事板或100%代码。
这个例子是垂直的:
下面是最简单的解释:
有一个空白的全屏场景 添加一个滚动视图。Control-drag从滚动视图拖到基本视图,添加左-右-上-下,全部为零。 在滚动视图中添加堆栈视图。从堆栈视图Control-drag到滚动视图,添加左-右-上-下,全部为零。 在堆栈视图中放置两个或三个标签。
为了清晰,标签的背景颜色为红色。设置标签高度为100。
现在设置每个UILabel的宽度: 令人惊讶的是,从UILabel控件拖动到滚动视图,而不是堆栈视图,并选择相同的宽度。
重复:
不要从UILabel控件拖动到UILabel的父控件,而是拖到祖父控件。(换句话说,一直到滚动视图,不要到堆栈视图。)
就是这么简单。这就是秘诀。
秘密提示——苹果臭虫: 只有一件物品是不行的!添加几个标签以使演示正常工作。
你就完成了。
提示:必须为每个新项添加高度。任何滚动堆栈视图中的每个项都必须具有固有大小(例如标签)或添加显式高度约束。
另一种方法:
回顾一下上面的方法:令人惊讶的是,将标签的宽度设置为滚动视图的宽度(而不是堆栈视图)。
这里有另一种方法……
从堆栈视图拖动到滚动视图,并添加一个“宽度相等”约束。这看起来很奇怪,因为你已经左右固定了,但这就是你怎么做的。不管看起来有多奇怪,这就是秘密。
所以你有两个选择:
令人惊讶的是,将堆栈视图中每个项的宽度设置为scrollview祖父类(而不是stackview父类)的宽度。
or
令人惊讶的是,设置一个“宽度相等”的stackview到scrollview -即使你有stackview的左右边固定到scrollview。
需要明确的是,只使用其中一种方法,不要同时使用两种方法。
为macOS Catalyst添加了一些新的视角。由于macOS应用程序支持窗口大小调整,你的UIStackView可能会从一个不可滚动的状态转换为一个可滚动的状态,反之亦然。这里有两件微妙的事情:
UIStackView被设计成适合它所能适应的所有区域。 在过渡期间,UIScrollView将尝试调整其边界大小,以考虑导航栏(或macOS应用程序中的工具栏)下新获得/丢失的区域。
不幸的是,这会造成一个无限循环。我不是非常熟悉UIScrollView和它的adjustdcontentinset,但从我的日志在其layoutSubviews方法,我看到以下行为:
一个人把窗户放大了。 UIScrollView试图缩小它的边界(因为不需要工具栏下面的区域)。 UIStackView。 不知何故UIScrollView不满意,决定恢复到更大的边界。这对我来说感觉很奇怪,因为我从日志中看到的是UIScrollView.bounds.height == UIStackView.bounds.height。 UIStackView。 然后循环到步骤2。
在我看来,有两个步骤可以解决这个问题:
UIStackView一致。top到UIScrollView.topMargin。 设置contentInsetAdjustmentBehavior为。never。
这里我关注的是一个垂直增长的UIStackView的垂直可滚动视图。对于水平对,相应更改代码。
希望它能在未来帮助到任何人。在网上找不到任何人提到这一点,我花了很长时间才弄清楚发生了什么。
推荐文章
- 如何删除默认的导航栏空间在SwiftUI导航视图
- 如何在iOS中使用Swift编程segue
- Swift -整数转换为小时/分钟/秒
- Swift:声明一个空字典
- 在成功提交我的应用程序后,“太多符号文件”
- 首先添加一个UIView,甚至是导航栏
- 我如何改变UIButton标题颜色?
- 在Swift中如何调用GCD主线程上的参数方法?
- NSLayoutConstraints是可动画的吗?
- iOS -构建失败,CocoaPods无法找到头文件
- CFNetwork SSLHandshake iOS 9失败
- 请求失败:不可接受的内容类型:文本/html使用AFNetworking 2.0
- 缺少推荐的图标文件-该包不包含iPhone / iPod Touch的应用程序图标,像素为“120x120”,png格式
- 以编程方式创建segue
- 如何使用Xcode创建。ipa文件?