假设我在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
}

其他回答

你可以试试ScrollableStackView: https://github.com/gurhub/ScrollableStackView

它是Objective-C和Swift兼容的库。它可以通过CocoaPods获得。

样本代码(Swift)

import ScrollableStackView

var scrollable = ScrollableStackView(frame: view.frame)
view.addSubview(scrollable)

// add your views with 
let rectangle = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 55))
rectangle.backgroundColor = UIColor.blue
scrollable.stackView.addArrangedSubview(rectangle)
// ...

样例代码(Objective-C)

@import ScrollableStackView

ScrollableStackView *scrollable = [[ScrollableStackView alloc] initWithFrame:self.view.frame];
scrollable.stackView.distribution = UIStackViewDistributionFillProportionally;
scrollable.stackView.alignment = UIStackViewAlignmentCenter;
scrollable.stackView.axis = UILayoutConstraintAxisVertical;
[self.view addSubview:scrollable];

UIView *rectangle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 55)];
[rectangle setBackgroundColor:[UIColor blueColor]];

// add your views with
[scrollable.stackView addArrangedSubview:rectangle]; 
// ...

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

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

为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!!!!!

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

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

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

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

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