为什么我的第二个按钮在使用自动布局约束时表现不同?

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 和约束是个坏主意。

这可以做到,但不能用锚点。尝试以下 NSLayoutConstraints:

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

然后使用锚点设置 widthheight

doneBtn.widthAnchor.constraint(equalToConstant: 55).isActive = true
doneBtn.heightAnchor.constraint(equalToConstant: 55).isActive = true

注意: 因为我们使用 .trailing.bottom 约束来表示 widthheight,所以可能需要将 doneBtnView 放入相同大小的容器视图中,因为这些值将位于父视图的坐标系中。通过使父视图大小完全相同,宽度将等于尾部约束,高度将等于底部约束。