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


当前回答

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

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

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

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

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

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

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

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

其他回答

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

如果你有一个约束,使堆栈视图垂直居中在滚动视图内,只需删除它。

这里投票最多的答案中的约束条件对我来说是有效的,我已经将在我的故事板中创建的约束条件的图像粘贴在下面。

我确实提到了两个问题,但其他人应该注意:

After adding constraints similar to those in in the accepted answer, I'd get the red autolayout error Need constraints for: X position or width. This was solved by adding a UILabel as a subview of the stack view. I'm adding the subviews programmatically, so I originally had no subviews on the storyboard. To get rid of the autolayout errors, add a subview to the storyboard, then remove it on load before adding your real subviews and constraints. I originally attempted to add UIButtons to the UIStackView. The buttons and views would load, but the scroll view would not scroll. This was solved by adding UILabels to the Stack View instead of buttons. Using the same constraints, this view hierarchy with the UILabels scrolls but the UIButtons does not. I'm confused by this issue, as the UIButtons do seem to have an IntrinsicContentSize (used by the Stack View). If anyone knows why the buttons don't work, I'd love to know why.

下面是我的视图层次结构和约束,供参考:

苹果的自动布局指南包括了一个关于使用滚动视图的完整部分。一些相关片段:

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

First and foremost design your view, preferably in something like Sketch or get an idea of what do you want as a scrollable content. After this make the view controller free form (choose from attribute inspector) and set height and width as per the intrinsic content size of your view (to be chosen from the size inspector). After this in the view controller put a scroll view and this is a logic, which I have found to be working almost all the times in iOS (it may require going through the documentation of that view class which one can obtain via command + click on that class or via googling) If you are working with two or more views then first start with a view, which has been introduced earlier or is more primitive and then go to the view which has been introduced later or is more modern. So here since scroll view has been introduced first, start with the scroll view first and then go to the stack view. Here put scroll view constraints to zero in all direction vis-a-vis its super view. Put all your views inside this scroll view and then put them in stack view.

当使用堆栈视图时

First start with grounds up(bottoms up approach), ie., if you have labels, text fields and images in your view, then lay out these views first (inside the scroll view) and after that put them in the stack view. After that tweak the property of stack view. If desired view is still not achieved, then use another stack view. If still not achieved then play with compression resistance or content hugging priority. After this add constraints to the stack view. Also think of using an empty UIView as filler view, if all of the above is not giving satisfactory results.

在创建视图之后,在母堆栈视图和滚动视图之间放置一个约束,同时约束子堆栈视图和母堆栈视图。 希望这个时候它能正常工作,否则你可能会从Xcode得到一个警告,给出建议,阅读它所说的并执行这些建议。希望现在你应该有一个工作视图按照你的期望:)。