“视图层次结构没有为约束做好准备”错误 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】:
尝试将left
和right
constraints 添加到view
而不是btn
。
【讨论】:
以上是关于“视图层次结构没有为约束做好准备”错误 Swift 3的主要内容,如果未能解决你的问题,请参考以下文章