假设我在UIStackView中添加了更多可以显示的视图,我如何让UIStackView滚动?


当前回答

在我的例子中,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。

为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的垂直可滚动视图。对于水平对,相应更改代码。

希望它能在未来帮助到任何人。在网上找不到任何人提到这一点,我花了很长时间才弄清楚发生了什么。

当使用故事板做这件事时,每个人似乎都错过了修复乘数! 当你按照上面的步骤在任何人教程和重置常数为0,同时检查乘数,并将其重置为1,它将采取了一些其他因素时,视觉链接保持到位

我发现我可以在UIStackView中简单地做一个loooooooooong文本块挤压或拉伸

简单的 向滚动视图添加约束 左上右下,弊为0

向指向滚动条Content Layout Guide的堆栈视图添加约束

然后从框架布局指南中添加等宽或等高的约束。 选择:宽度如果内容需要垂直滚动,高度如果它需要水平滚动。

这是关键。编辑每个约束并将常数重置为0并将乘数设置回1!!!!!

如果你不这样做,它就会摇摇欲坠

如果它工作,你可以点击内部内容和鼠标滚动

将stackview中的动态元素嵌入到scrollview中的一种简单方法。在XIB中,在UIScrollView中添加一个UIStackView,并添加stackview适合scrollview的约束(top, bottom, lead, trail),并添加一个约束来匹配它们之间的水平中心。但是将最后一个约束标记为“在构建时移除”。它使XIB高兴,避免错误。

水平滚动示例:

然后:

然后在你的代码中,像这样在你的stackview中添加按钮这样的元素:

array.forEach { text in
     let button = ShadowButton(frame: .zero)
     button.setTitle(text, for: .normal)
     myStackView.addArrangedSubview(button)
     button.heightAnchor.constraint(equalToConstant: 40).isActive = true
     button.widthAnchor.constraint(equalToConstant: 80).isActive = true
}

我给你一个正确的解决方案

对于 Xcode 11+

步骤1: 添加一个ScrollView并调整它的大小

步骤2: 为ScrollView添加约束

步骤3: 添加一个StackView到ScrollView,并调整它的大小。

步骤4: 为StackView添加约束(Stask View ->内容布局指南->“领先,顶部,后面,底部”)

步骤4.1: 正确的约束->常量(…->常量= 0)

步骤5: 为StackView添加约束(Stask View -> Frame Layout Guide -> "Equal width ")

步骤6示例: 添加两个带有HeightConstraints和RUN的UIView

希望对大家有用