我真的不明白如何在创建自定义视图时使用布局。
主要问题在这里:
rect.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.5),
rect.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 1),
如果我使用乘法器,则可以正常工作。但是,如果我使用常量:
rect.widthAnchor.constraint(equalToConstant: self.frame.width)
它不起作用。
如何为我的自定义视图autoLayout约束使用任何superView框架大小?
class MainView: UIView {
lazy var rect: UIView = {
let view = UIView()
view.backgroundColor = .green
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .red
layout()
}
func layout() {
addSubview(rect)
self.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
rect.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.5),
rect.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 1),
rect.centerYAnchor.constraint(equalTo: centerYAnchor),
rect.centerXAnchor.constraint(equalTo: centerXAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class ViewController: UIViewController {
let mainView = MainView(frame: .zero)
override func loadView() {
self.view = mainView
}
如果我使用乘法器,则可以正常工作。但是,如果我使用常量:
rect.widthAnchor.constraint(equalToConstant: self.frame.width)
这势必会发生,在您的viewController中,您将mainView
实例化为let mainView = MainView(frame: .zero)
这将以帧为零触发init
的MainView
您在init
内部调用布局
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .red
layout()
}
所以您实际上在MainView
框架为Zero
时调用布局因此宽度设置为零
[请仔细阅读声明,在这种情况下,您要将矩形宽度锚定为rect.widthAnchor.constraint(equalToConstant: self.frame.width)
,因此,在以后的UI循环阶段,您的rect.widthAnchor.constraint(equalToConstant: 0)
获得适当的宽度,您的矩形将始终为零因为您将其设置为常数0值
**constant**
,这为什么起作用?
[这里您说您的rect的宽度锚点等于MainView
的宽度锚点,您未将rect的宽度锚点设置为常数,而是将其设置为与MainView的宽度锚点匹配,因此当MainView的帧最终设置为适当的值,您的rect也将更新其宽度以匹配MainViews的宽度。
坦率地说,rect.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 1)
在这种情况下没有任何意义,因为您要使矩形的宽度与MainView的宽度相匹配,如果您希望矩形的宽度与MainView的宽度成比例地变化(例如50%只有MainView宽度等),乘数才有意义
自动布局约束只不过是数学方程式,正确理解/可视化它们是获得具有约束条件的完美UI的关键
希望这会有所帮助