【发布时间】:2020-07-02 09:10:22
【问题描述】:
我正在努力应用以下约束:
documentTypeCircle.topAnchor.constraint(equalTo: middleContentScrollView.topAnchor, constant: self.frame.height * 0.03).isActive = true
documentStepTitle.topAnchor.constraint(equalTo: documentTypeCircle.bottomAnchor, constant: self.frame.height * 0.05).isActive = true
documentStepTableView.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: self.frame.width * 0.05).isActive = true
documentStepTableView.widthAnchor.constraint(equalToConstant: self.frame.width * 0.73).isActive = true
uploadImageView.topAnchor.constraint(equalTo: documentStepTableView.bottomAnchor, constant: self.frame.height * 0.05).isActive = true
我需要访问self.frame.width,但是值是0。
我在 ViewController 的 loadView() 中添加了这个视图,因为它是推荐的方法:
override func loadView() {
self.view = CustomView(frame: .zero)
}
如何确保 self.frame.width 提供整个视图的宽度,而不是返回 0? 如果我将约束逻辑移动到 layoutSubviews() 它可以正常工作,但是 多次创建约束 这似乎是不干净的解决方案:
override open func layoutSubviews() {
documentTypeCircle.topAnchor.constraint(equalTo: middleContentScrollView.topAnchor, constant: self.frame.height * 0.03).isActive = true
documentStepTitle.topAnchor.constraint(equalTo: documentTypeCircle.bottomAnchor, constant: self.frame.height * 0.05).isActive = true
documentStepTableView.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: self.frame.width * 0.05).isActive = true
documentStepTableView.widthAnchor.constraint(equalToConstant: self.frame.width * 0.73).isActive = true
uploadImageView.topAnchor.constraint(equalTo: documentStepTableView.bottomAnchor, constant: self.frame.height * 0.05).isActive = true
}
但是,如果我使用 UIScreen.main.bounds 而不是 .zero 实例化视图,即使在 customView 的 init() 中它也能正常工作。但是,我很困惑为什么会使用 UIScreen.main.bounds 而不是 .zero 正确绘制自定义视图。即使使用 .zero,自动布局也不应该处理这个问题吗?
编辑
我找到了recommended approach,但无法使其适用于我们的案例。新布局看起来不像旧布局,所有约束似乎都无处不在
我的新约束和用框架注释的旧约束:
//documentTypeCircle.topAnchor.constraint(equalTo: middleContentScrollView.topAnchor, constant: self.frame.height * 0.03).isActive = true
NSLayoutConstraint(item: documentTypeCircle, attribute: .top, relatedBy: .equal,
toItem: middleContentScrollView, attribute: .top, multiplier: 0.03, constant: 0).isActive = true
//documentStepTitle.topAnchor.constraint(equalTo: documentTypeCircle.bottomAnchor, constant: self.frame.height * 0.05).isActive = true
NSLayoutConstraint(item: documentStepTitle, attribute: .top, relatedBy: .equal,
toItem: documentTypeCircle, attribute: .bottom, multiplier: 0.05, constant: 0).isActive = true
//documentStepTableView.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: self.frame.width * 0.05).isActive = true
NSLayoutConstraint(item: documentStepTableView, attribute: .centerX, relatedBy: .equal,
toItem: self, attribute: .centerX, multiplier: 0.05, constant: 0).isActive = true
//documentStepTableView.widthAnchor.constraint(equalToConstant: self.frame.width * 0.73).isActive = true
NSLayoutConstraint(item: documentStepTableView, attribute: .width, relatedBy: .equal,
toItem: self, attribute: .width, multiplier: 0.73, constant: 0).isActive = true
//uploadImageView.topAnchor.constraint(equalTo: documentStepTableView.bottomAnchor, constant: self.frame.height * 0.05).isActive = true
NSLayoutConstraint(item: uploadImageView, attribute: .top, relatedBy: .equal,
toItem: documentStepTableView, attribute: .bottom, multiplier: 0.05, constant: 0).isActive = true
Perhaps I am mixing anchor with NSLayoutConstraint, however I feel like it is impossible to achieve same layout behaviour with auto layout, without using frames.
【问题讨论】:
-
您确定要让您的约束具有
self.frame.height * 0.03的常量吗?如果self.frame.height发生变化怎么办?您是否希望约束的常量保持不变,而不是使用新的self.frame.height? -
@Sweeper 我不会以任何方式更改约束。我需要在开始时绘制整个 UI 并且不要更改它。问题是,如果我通过 .zero,那么我的滚动视图将不可见,因为我无法正确计算约束。如果我通过 UIScreen.main.bounds 我可以计算,但我不确定它是否是正确的方法,因为如果你使用自动布局,建议通过 .zero 。也许我需要在设置约束之前调用 layoutIfNeeded()?
标签: swift autolayout interface-builder