UIScrollView内的UIStackView会一直增长到最大高度,然后滚动

时间:2019-01-22 17:39:49

标签: ios swift uiscrollview autolayout uistackview

我正在寻找一个视图,该视图将随着添加的子视图而增长。首先,高度将为零,然后应随着我添加子视图的增加而增大,直到达到最大大小为止,然后我希望它变得可滚动。

如果我使用UIScrollView内的UIView构建此对象,并手动从上到下设置约束,则它将按预期工作。但是,我觉得使用UIStackView应该可以做到这一点,但是当我尝试滚动视图不增长,或者scrollView的contentSize卡在最大高度时,就不会滚动。我已经玩了一段时间,并认为它实际上可能是UIStackView和Autolayout的错误,但希望我只是错过了一些东西。将UIStackView包装在容器UIView中无济于事。

这是一个完整的视图控制器,可以显示问题(在任意位置点按即可向滚动视图添加标签)

import UIKit

class DumbScrollStack: UIViewController {

    let stack = UIStackView()
    let scrollView = UIScrollView()

    override func viewDidLoad() {
        super.viewDidLoad()

        //Setup
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(addLabel)))
        stack.axis = .vertical
        view.backgroundColor = .blue
        scrollView.backgroundColor = .red

        //Add scroll view and setup position
        view.addSubview(scrollView)
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true

        //Set maximum height
        scrollView.heightAnchor.constraint(lessThanOrEqualToConstant: 100).isActive = true

        //add stack
        scrollView.addSubview(stack)
        stack.translatesAutoresizingMaskIntoConstraints = false

        //setup scrollView content size constraints
        stack.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        stack.leftAnchor.constraint(equalTo: scrollView.leftAnchor).isActive = true
        stack.rightAnchor.constraint(equalTo: scrollView.rightAnchor).isActive = true
        stack.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
        stack.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true

        // Keep short if stack height is lower than scroll height
        // With this constraint the scrollView grows as expected, but doesn't scroll when it goes over 100px
        // Without this constraint the scrollView is always 100px tall but it does scroll
        let constraint = scrollView.heightAnchor.constraint(equalTo: stack.heightAnchor)
        constraint.priority = UILayoutPriority(rawValue: 999)
        constraint.isActive = true

        addLabel()
    }

    @objc func addLabel() {
        let label = UILabel()
        label.backgroundColor = .gray
        label.text = "Hello"
        stack.addArrangedSubview(label)
    }
}

2 个答案:

答案 0 :(得分:4)

添加此

label.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1000), for: .vertical)

或对此块发表评论

let constraint = scrollView.heightAnchor.constraint(equalTo: stack.heightAnchor)
constraint.priority = UILayoutPriority(rawValue: 999)
constraint.isActive = true

或使其低于750(标签的默认垂直压缩率)

constraint.priority = UILayoutPriority(rawValue: 749)

问题是标签的垂直压缩优先级低于999,这总是使堆栈等于scrollview的高度,因此没有滚动

答案 1 :(得分:0)

您是否考虑过使用UICollectionView?听起来像是您要重建的内容。

确保将“已启用滚动”设置为true并设置滚动方向。