为什么我的第二个按钮在使用自动布局约束时表现不同?
Why is my second button behaving different when using auto layout constraints?
我不明白为什么我的按钮在以编程方式使用自动布局约束时表现不同。
当设置包含我的 cancelBtn 的视图时,一切正常:
let cancelBtnView = TriangularView(frame: CGRect(x: 0, y: 0, width: 300, height: 150))
let cancelBtn = UIButton()
cancelBtnView.addSubview(cancelBtn)
cancelBtn.titleLabel!.font = UIFont.fontAwesome(ofSize: 35, style: .regular)
cancelBtn.setTitle(String.fontAwesomeIcon(name: .times), for: .normal)
cancelBtn.frame = CGRect(x: cancelBtnView.bounds.width / 16, y: cancelBtnView.bounds.height / 2 ,width: 55, height: 55)
我得到以下布局:
为我的 doneBtn 设置视图时,我得到了不同的输出:
let doneBtnView = TriangularView()
doneBtnView.translatesAutoresizingMaskIntoConstraints = false
doneBtnView.widthAnchor.constraint(equalToConstant: 300).isActive = true
doneBtnView.heightAnchor.constraint(equalToConstant: 150).isActive = true
doneBtnView.trailingAnchor.constraint(equalTo: actionButtonView.trailingAnchor).isActive = true
doneBtnView.bottomAnchor.constraint(equalTo: actionButtonView.bottomAnchor).isActive = true
let doneBtn = UIButton()
doneBtnView.addSubview(doneBtn)
doneBtn.titleLabel!.font = UIFont.fontAwesome(ofSize: 35, style: .regular)
doneBtn.setTitle(String.fontAwesomeIcon(name: .check), for: .normal)
doneBtn.translatesAutoresizingMaskIntoConstraints = false
doneBtn.widthAnchor.constraint(equalToConstant: 55).isActive = true
doneBtn.heightAnchor.constraint(equalToConstant: 55).isActive = true
doneBtn.leadingAnchor.constraint(equalTo: doneBtnView.leadingAnchor, constant: doneBtnView.bounds.width / 16).isActive = true
doneBtn.bottomAnchor.constraint(equalTo: doneBtnView.bottomAnchor, constant: doneBtnView.bounds.height / 2).isActive = true
以编程方式为我的 doneBtn 设置约束,我得到以下信息:
doneBtnView 的约束是以编程方式设置的,因为我想将它固定到其超级视图的右下角。
您的问题是,在为 doneBtn
设置约束时,您正在查看另一个视图的边界,但这些边界尚未设置,因为布局尚未发生。一般来说,结合使用 frame/bounds 和约束是个坏主意。
这可以做到,但不能用锚点。尝试以下 NSLayoutConstraint
s:
NSLayoutConstraint(item: doneBtn, attribute: .leading, relatedBy: .equal,
toItem: doneBtnView, attribute: .trailing, multiplier: 1/16, constant: 0).isActive = true
NSLayoutConstraint(item: doneBtn, attribute: .top, relatedBy: .equal,
toItem: doneBtnView, attribute: .bottom, multiplier: 1/2, constant: 0).isActive = true
然后使用锚点设置 width
和 height
:
doneBtn.widthAnchor.constraint(equalToConstant: 55).isActive = true
doneBtn.heightAnchor.constraint(equalToConstant: 55).isActive = true
注意: 因为我们使用 .trailing
和 .bottom
约束来表示 width
和 height
,所以可能需要将 doneBtnView
放入相同大小的容器视图中,因为这些值将位于父视图的坐标系中。通过使父视图大小完全相同,宽度将等于尾部约束,高度将等于底部约束。
我不明白为什么我的按钮在以编程方式使用自动布局约束时表现不同。
当设置包含我的 cancelBtn 的视图时,一切正常:
let cancelBtnView = TriangularView(frame: CGRect(x: 0, y: 0, width: 300, height: 150))
let cancelBtn = UIButton()
cancelBtnView.addSubview(cancelBtn)
cancelBtn.titleLabel!.font = UIFont.fontAwesome(ofSize: 35, style: .regular)
cancelBtn.setTitle(String.fontAwesomeIcon(name: .times), for: .normal)
cancelBtn.frame = CGRect(x: cancelBtnView.bounds.width / 16, y: cancelBtnView.bounds.height / 2 ,width: 55, height: 55)
我得到以下布局:
为我的 doneBtn 设置视图时,我得到了不同的输出:
let doneBtnView = TriangularView()
doneBtnView.translatesAutoresizingMaskIntoConstraints = false
doneBtnView.widthAnchor.constraint(equalToConstant: 300).isActive = true
doneBtnView.heightAnchor.constraint(equalToConstant: 150).isActive = true
doneBtnView.trailingAnchor.constraint(equalTo: actionButtonView.trailingAnchor).isActive = true
doneBtnView.bottomAnchor.constraint(equalTo: actionButtonView.bottomAnchor).isActive = true
let doneBtn = UIButton()
doneBtnView.addSubview(doneBtn)
doneBtn.titleLabel!.font = UIFont.fontAwesome(ofSize: 35, style: .regular)
doneBtn.setTitle(String.fontAwesomeIcon(name: .check), for: .normal)
doneBtn.translatesAutoresizingMaskIntoConstraints = false
doneBtn.widthAnchor.constraint(equalToConstant: 55).isActive = true
doneBtn.heightAnchor.constraint(equalToConstant: 55).isActive = true
doneBtn.leadingAnchor.constraint(equalTo: doneBtnView.leadingAnchor, constant: doneBtnView.bounds.width / 16).isActive = true
doneBtn.bottomAnchor.constraint(equalTo: doneBtnView.bottomAnchor, constant: doneBtnView.bounds.height / 2).isActive = true
以编程方式为我的 doneBtn 设置约束,我得到以下信息:
doneBtnView 的约束是以编程方式设置的,因为我想将它固定到其超级视图的右下角。
您的问题是,在为 doneBtn
设置约束时,您正在查看另一个视图的边界,但这些边界尚未设置,因为布局尚未发生。一般来说,结合使用 frame/bounds 和约束是个坏主意。
这可以做到,但不能用锚点。尝试以下 NSLayoutConstraint
s:
NSLayoutConstraint(item: doneBtn, attribute: .leading, relatedBy: .equal,
toItem: doneBtnView, attribute: .trailing, multiplier: 1/16, constant: 0).isActive = true
NSLayoutConstraint(item: doneBtn, attribute: .top, relatedBy: .equal,
toItem: doneBtnView, attribute: .bottom, multiplier: 1/2, constant: 0).isActive = true
然后使用锚点设置 width
和 height
:
doneBtn.widthAnchor.constraint(equalToConstant: 55).isActive = true
doneBtn.heightAnchor.constraint(equalToConstant: 55).isActive = true
注意: 因为我们使用 .trailing
和 .bottom
约束来表示 width
和 height
,所以可能需要将 doneBtnView
放入相同大小的容器视图中,因为这些值将位于父视图的坐标系中。通过使父视图大小完全相同,宽度将等于尾部约束,高度将等于底部约束。