“视图层次结构未准备好约束”错误 Swift 3。

8
我试图通过编程方式添加按钮并设置约束,但我一直收到这个错误,并且无法弄清楚我的代码有什么问题。我已经查看了其他问题,但在我的情况下它们没有提供太多帮助。
    btn.setTitle("mybtn", for: .normal)
    btn.setTitleColor(UIColor.blue, for: .normal)
    btn.backgroundColor = UIColor.lightGray
    view.addSubview(btn)
    btn.translatesAutoresizingMaskIntoConstraints = false

    let left = NSLayoutConstraint(item: btn, attribute: .leftMargin, relatedBy: .equal, toItem: view, attribute: .leftMargin, multiplier: 1.0, constant: 0)

    let right = NSLayoutConstraint(item: btn, attribute: .rightMargin, relatedBy: .equal, toItem: view, attribute: .rightMargin, multiplier: 1.0, constant: 0)

    let top = NSLayoutConstraint(item: btn, attribute: .top, relatedBy: .equal, toItem: topLayoutGuide, attribute: .bottom, multiplier: 1.0, constant: 0)

    btn.addConstraints([left, right, top])

1
你把这段代码放在哪里? - Sweeper
3个回答

19
当你添加约束到一个视图时,“任何涉及到的视图[在约束中]必须是接收视图本身或接收视图的子视图”。你正在将约束添加到btn,所以它不理解约束引用的view应该如何处理,因为它既不是btn,也不是btn的子视图。如果你将约束添加到view而不是btn,则可以解决错误。
或者更好的方法是,像Khalid建议的那样使用activate,这样你就不需要担心在视图层次结构中添加约束的位置:
let btn = UIButton(type: .system)
btn.setTitle("mybtn", for: .normal)
btn.setTitleColor(.blue, for: .normal)
btn.backgroundColor = .lightGray
view.addSubview(btn)
btn.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
    btn.leftAnchor.constraint(equalTo: view.leftAnchor),
    btn.rightAnchor.constraint(equalTo: view.rightAnchor),
    btn.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor)
])

谢谢。一直在寻找这个。 - Amorn Narula

3
使用“激活约束”功能。自iOS 9起,您可以使用“激活”功能。
 btn.setTitle("mybtn", for: .normal)
 btn.setTitleColor(UIColor.blue, for: .normal)
 btn.backgroundColor = UIColor.gray

 btn.translatesAutoresizingMaskIntoConstraints = false
 self.view.addSubview(btn)


let left = NSLayoutConstraint(item: btn, attribute: .leftMargin, relatedBy: .equal, toItem: view, attribute: .leftMargin, multiplier: 1.0, constant: 0)

let right = NSLayoutConstraint(item: btn, attribute: .rightMargin, relatedBy: .equal, toItem: view, attribute: .rightMargin, multiplier: 1.0, constant: 0)

let top = NSLayoutConstraint(item: btn, attribute: .top, relatedBy: .equal, toItem: topLayoutGuide, attribute: .bottom, multiplier: 1.0, constant: 0)

// here you have to call activate constraints everything will work     
NSLayoutConstraint.activate([left, right, top])

示例项目


那个 NSLayoutConstraint.activate 方法实际上只是一个快捷方式。来自苹果文档的解释:激活或取消约束会在此约束管理的项目的最近公共祖先视图上调用 addConstraint(_:)removeConstraint(_:) 方法。 - Paulo Mattos
抱歉如果我表现不礼貌。 - Khalid Afridi
这就是为什么我非常喜欢SO社区的原因...我们让代码说话 :-) KhalidAfridi,@Rob - Paulo Mattos

0

尝试将leftright约束添加到view而不是btn


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接