“视图层次结构没有为约束做好准备”错误 Swift 3

Posted

技术标签:

【中文标题】“视图层次结构没有为约束做好准备”错误 Swift 3【英文标题】:"The view hierarchy is not prepared for the constraint" error Swift 3 【发布时间】:2017-04-16 11:38:36 【问题描述】:

我正在尝试添加一个按钮并以编程方式设置约束,但我不断收到此错误并且无法弄清楚我的代码有什么问题。我在这里查看了其他问题,但它们对我的情况并没有太大帮助。

    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】:

当adding constraints 指向一个视图时,“[约束中] 所涉及的任何视图必须要么是接收视图本身,要么是接收视图的子视图”。您将约束添加到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)
])

【讨论】:

谢谢。一直在找这个。【参考方案2】:

使用激活约束。在 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])

example project

【讨论】:

那个NSLayoutConstraint.activate 方法实际上只是一个捷径兄弟。来自 Apple 文档:在此约束管理的项目的最近共同祖先的视图上激活或停用约束调用 addConstraint(_:)removeConstraint(_:) 对不起,如果我不礼貌 这就是我如此热爱 SO 社区的原因……我们让代码来说话:-) KhalidAfridi,@Rob【参考方案3】:

尝试将leftrightconstraints 添加到view 而不是btn

【讨论】:

以上是关于“视图层次结构没有为约束做好准备”错误 Swift 3的主要内容,如果未能解决你的问题,请参考以下文章

在扩展中出现错误“视图层次结构没有为约束做好准备”

视图层次结构没有为约束做好准备?

视图层次结构没有为约束做好准备

视图层次结构没有为约束做好准备:无法找到问题

uiscrollview的自动布局,视图层次结构没有为约束做好准备

为 UITableCellView 中的视图添加 NSLayoutConstraint