【发布时间】:2019-06-16 05:50:52
【问题描述】:
我正在寻找一个视图,它会随着子视图的添加而增长。起初高度为零,然后随着我添加子视图而增长,直到达到最大尺寸,然后我希望它变得可滚动。
如果我在 UIScrollView 中使用 UIView 构建它并手动设置从上到下的约束,它会按预期工作。但是,我觉得使用 UIStackView 应该可以做到这一点,但是当我尝试滚动视图不增长,或者滚动视图的 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)
}
}
【问题讨论】:
-
您尝试调整滚动视图大小是否有原因?
-
我发现这个代码示例非常有用,可以让我的 scrollView 动态调整大小。但我确实花了一段时间才弄清楚你是怎么做到的。我认为其他人应该注意的关键点是有两个
heightAnchor约束。第一个是范围(通过lessThanOrEqualToConstant)第二个等于其内容大小,但优先级较低。理想情况下,AutoLayout 可以使它们都有效,但如果不能,它知道忽略第二个,这会使实际内容大于滚动视图,从而启用滚动。
标签: ios swift uiscrollview autolayout uistackview