底线,如果您明确定义内容视图和滚动视图之间的约束(将contentSize
根据TN2154定义),然后明确定义内容视图及其子视图之间的约束,那么,是的,它将正确定义大小滚动视图的contentSize
.
我建议使用视图调试器,并查看右侧面板中的约束:
在特定的屏幕快照中,我在滚动视图的内容视图中选择了第三个子视图(深蓝色),它告诉我们活动约束是:
- 从容器前缘偏移 10(绿色)
- 从容器后缘偏移 10(绿色)
- 从上面的子视图偏移 10(深红色)
- 固定高度 200(我这样做是因为它没有隐式高度)
- 主视图的宽度(亮红色)减去 20(以便它占据适当数量的水平空间,同样因为没有隐式宽度)
- 从下面的子视图偏移 10(浅蓝色)
因此,您只需单击各种子视图和容器,并确认约束正是您想要的。很容易错过一个约束和/或无法激活一个约束,整个事情就崩溃了。
By the way, sometimes it's not obvious what views the constraints are between, but if you tap on the constraints button, , when a view is selected, it will highlight just the views to which you have constraints (in this example, to the content视图,到上面和下面的子视图,以及主视图;因为滚动视图(黄色)和第一个子视图(紫色)都没有对第三个子视图有任何约束,所以你只看到它们的线框,而不是它们的内容) :
请注意,这是一个示例,我想我会向您展示我使用的约束,以便自动布局可以contentSize
根据内容视图和具有完全满足、明确约束的子视图正确计算:
let contentView = ContentView()
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.backgroundColor = randomColor()
scrollView.addSubview(contentView)
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor)
])
var previousView: UIView?
for _ in 0 ..< 4 {
let subview = SomeSubview()
subview.translatesAutoresizingMaskIntoConstraints = false
subview.backgroundColor = self.randomColor()
contentView.addSubview(subview)
NSLayoutConstraint.activate([
subview.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
subview.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
subview.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -20),
subview.heightAnchor.constraint(equalToConstant: 200)
])
if previousView != nil {
subview.topAnchor.constraint(equalTo: previousView!.bottomAnchor, constant: 10).isActive = true
} else {
subview.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
}
previousView = subview
}
previousView?.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10).isActive = true
在您的示例中让我感到奇怪的是,您同时设置了edges
(我假设是设置顶部、底部、前导和尾随约束)和height
. 不需要设置内容视图的高度。你可以定义边缘,你应该很好。高度由其子视图的约束决定。
如果您的子视图看起来布局正确,但滚动视图的contentSize
设置不正确,那么罪魁祸首可能是最后一个子视图和您的内容视图之间缺少底部约束。
如果您仍然遇到问题,我建议您创建一个简化但完整的问题示例。您共享的代码不足。但我们也不想看到您的所有代码或您的特定 UI。相反,创建一个独立的简化示例来显示您描述的问题。只有我们可以重现您的问题,我们才能帮助您解决它。