在运行时向滚动视图添加多个元素时,您可能会发现使用UIStackView 会更容易...如果设置正确,它会随着每个添加的对象自动增加高度。
举个简单的例子……
1) 首先添加一个UIScrollView(我给它一个蓝色背景以便于查看)。将其在所有 4 个方面都约束为零:
请注意,我们看到“红色圆圈”表示缺少/冲突的约束。暂时忽略它。
2) 在滚动视图中添加一个UIView 作为“内容视图”(我给它一个systemYellow 背景以便于查看)。在内容布局指南的所有 4 个方面将其限制为零——这将(最终)定义滚动视图的内容大小。还要将其限制为等宽和等高框架布局指南:
重要步骤:选择高度约束,然后在Size Inspector 窗格中选择Placeholder - Remove at build time 复选框。这将在设计时满足 IB 中的自动布局,但将允许该视图的高度根据需要缩小/增长。
3) 将垂直UIStackView 添加到“内容视图”。将其在所有 4 个面上都约束为零。将其属性配置为Fill / Fill / 8(如下图):
4) 在视图控制器类的堆栈视图中添加一个@IBOutlet 连接。现在,在运行时,当您将 UI 元素添加到堆栈视图时,您的所有“可滚动性”都将由自动布局处理。
这是一个示例类:
class DynaScrollViewController: UIViewController {
@IBOutlet var theStackView: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
// local var so we can reuse it
var theLabel = UILabel()
var theImageView = UIImageView()
// create a new label
theLabel = UILabel()
// this gets set to false when the label is added to a stack view,
// but good to get in the habit of setting it
theLabel.translatesAutoresizingMaskIntoConstraints = false
// multi-line
theLabel.numberOfLines = 0
// cyan background to make it easy to see
theLabel.backgroundColor = .cyan
// add 9 lines of text to the label
theLabel.text = (1...9).map({ "Line \($0)" }).joined(separator: "\n")
// add it to the stack view
theStackView.addArrangedSubview(theLabel)
// add another label
theLabel = UILabel()
// multi-line
theLabel.numberOfLines = 0
// yellow background to make it easy to see
theLabel.backgroundColor = .yellow
// add 5 lines of text to the label
theLabel.text = (1...5).map({ "Line \($0)" }).joined(separator: "\n")
// add it to the stack view
theStackView.addArrangedSubview(theLabel)
// create a new UIImageView
theImageView = UIImageView()
// this gets set to false when the label is added to a stack view,
// but good to get in the habit of setting it
theImageView.translatesAutoresizingMaskIntoConstraints = false
// load an image for it - I have one named background
if let img = UIImage(named: "background") {
theImageView.image = img
}
// let's give the image view a 4:3 width:height ratio
theImageView.widthAnchor.constraint(equalTo: theImageView.heightAnchor, multiplier: 4.0/3.0).isActive = true
// add it to the stack view
theStackView.addArrangedSubview(theImageView)
// add another label
theLabel = UILabel()
// multi-line
theLabel.numberOfLines = 0
// yellow background to make it easy to see
theLabel.backgroundColor = .green
// add 2 lines of text to the label
theLabel.text = (1...2).map({ "Line \($0)" }).joined(separator: "\n")
// add it to the stack view
theStackView.addArrangedSubview(theLabel)
// add another UIImageView
theImageView = UIImageView()
// this gets set to false when the label is added to a stack view,
// but good to get in the habit of setting it
theImageView.translatesAutoresizingMaskIntoConstraints = false
// load a different image for it - I have one named AquariumBG
if let img = UIImage(named: "AquariumBG") {
theImageView.image = img
}
// let's give this image view a 1:1 width:height ratio
theImageView.heightAnchor.constraint(equalTo: theImageView.widthAnchor, multiplier: 1.0).isActive = true
// add it to the stack view
theStackView.addArrangedSubview(theImageView)
}
}
如果已遵循这些步骤,您应该会得到以下输出:
并且,在滚动到底部之后: