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


当前回答

将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
}

其他回答

在你的场景中放置一个滚动视图,并调整它的大小,使它充满场景。然后,在滚动视图中放置一个堆栈视图,并在堆栈视图中放置添加项按钮。一旦一切就绪,就设置以下约束条件:

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

代码:堆栈视图。宽度=滚动视图。宽度是关键。

对于嵌套视图或单栈视图,滚动视图必须与根视图设置固定宽度。滚动视图内部的主堆栈视图必须设置相同的宽度。[我的滚动视图是一个视图的波纹,忽略它]

在UIStackView和 UIScrollView。

如果有人在找水平滚动视图

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()
}

水平滚动(UIScrollView中的UIStackView)

用于水平滚动。首先,创建一个UIStackView和一个UIScrollView,并按以下方式将它们添加到您的视图中:

let scrollView = UIScrollView()
let stackView = UIStackView()

scrollView.addSubview(stackView)
view.addSubview(scrollView)

记住在UIStackView和UIScrollView上设置translatesAutoresizingMaskIntoConstraints为false:

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。

文本Insets

另一个你可能会发现有用的特性是,因为UIStackView保存在UIScrollView中,你现在可以访问文本insets,使事情看起来更漂亮一点。

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

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得到一个警告,给出建议,阅读它所说的并执行这些建议。希望现在你应该有一个工作视图按照你的期望:)。