Swift iOS:将两个UI元素约束到同一位置的方法及异常排查
iOS约束异常解决:锚点无共同祖先问题
在Swift iOS开发中,先将UILabel约束到middleUIView中心,布局正常。后续移除该Label并尝试把continueButton约束到同一middleUIView中心时,触发NSGenericException异常,提示约束锚点无共同祖先。
相关代码如下:
override func viewDidLoad() { super.viewDidLoad() // Middle UI View view.addSubview(middleUIView) NSLayoutConstraint.activate([ middleUIView.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor), middleUIView.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor), middleUIView.topAnchor.constraint(equalTo: sosButton.bottomAnchor), middleUIView.bottomAnchor.constraint(equalTo: textView.topAnchor) ]) // Middle Label middleUIView.addSubview(middleUILabel) NSLayoutConstraint.activate([ middleUILabel.centerXAnchor.constraint(equalTo: middleUIView.centerXAnchor), middleUILabel.centerYAnchor.constraint(equalTo: middleUIView.centerYAnchor) ]) } func createButton() { middleUILabel.removeFromSuperview() middleUIView.removeConstraints(middleUIView.constraints) // It errors out here NSLayoutConstraint.activate([ continueButton.widthAnchor.constraint(equalToConstant: 150), continueButton.heightAnchor.constraint(equalToConstant: 50), continueButton.centerXAnchor.constraint(equalTo: middleUIView.centerXAnchor), continueButton.centerYAnchor.constraint(equalTo: middleUIView.centerYAnchor) ]) }
错误信息:
Terminating app due to uncaught exception 'NSGenericException',
reason: 'Unable to activate constraint with anchors
<NSLayoutXAxisAnchor:0x2807ffd80
"UIButton:0x135425fc0'Continue'.centerX"> and
<NSLayoutXAxisAnchor:0x2807d4b00 "UIView:0x135425700.centerX"> because
they have no common ancestor. Does the constraint or its anchors
reference items in different view hierarchies? That's illegal.'
解决方法
- 问题根源:
continueButton没有被添加到middleUIView的子视图层级中,导致两个视图不在同一视图树里,自然没有共同祖先,无法建立约束。另外你错误删除了middleUIView自身的布局约束,这会破坏整个页面布局,完全没必要。 - 修正步骤:
- 在激活约束前,先把按钮加入
middleUIView的子视图; - 删掉
middleUIView.removeConstraints(middleUIView.constraints)这行代码。
- 在激活约束前,先把按钮加入
修正后的createButton函数:
func createButton() { middleUILabel.removeFromSuperview() // 先将按钮添加到middleUIView的子视图层级 middleUIView.addSubview(continueButton) NSLayoutConstraint.activate([ continueButton.widthAnchor.constraint(equalToConstant: 150), continueButton.heightAnchor.constraint(equalToConstant: 50), continueButton.centerXAnchor.constraint(equalTo: middleUIView.centerXAnchor), continueButton.centerYAnchor.constraint(equalTo: middleUIView.centerYAnchor) ]) }
内容的提问来源于stack exchange,提问作者Shiv Nik
相关产品推荐
相关产品推荐

