我是一位新手快速开发人员,遵循一个好的iOS 9 Swift书中的代码示例。本书刚刚演示了如何在视图层次结构的两个不同分支中的两个对象(标签,按钮)之间添加约束(以代码形式)。视图层次结构不准备
myLabel位于顶部视图控制器中的viewBB容器中。 myButton位于viewBB之外的顶部视图控制器中。
示例代码正常工作。但是对于练习,我想在viewBB中创建第二个label2,并将其位置限制为与myLabel偏移。所以这两个标签(我认为)都在viewBB中。
在代码中创建label2并在代码中添加约束可以正常工作。
但是......如果我在界面生成器中创建了label2,并尝试删除IB约束并将其替换为我自己的,那么构建成功,但应用程序崩溃时出现通常的“视图层次结构不准备”错误。
***有趣的是错误消息提到一个标签和一个按钮,暗示书本示例代码(我称之为下面的BLOCK 0)是罪犯。
我在做什么错? (我读过的一切,我能找到的错误信息,包括在这个论坛4个员额但我不知所措知道为什么书代码失败。)
错误消息:
2016-02-25 12:52:32.796 TwoViewConstraints [5713:1860768] 未对约束准备视图层次结构:NSLayoutConstraint:0x7c9ce990 UILabel:0x7c9dbec0'Label'.centerX == UIButton:0x7c9deed0'Button'.centerX
当添加到视图中时,约束条目必须是该视图的后代(或视图本身)。如果在组装视图层次结构之前需要解析约束,这将会崩溃。打破 - [UIView(UIConstraintBasedLayout)_viewHierarchyUnpreparedForConstraint:]进行调试。从调试
消息:由于终止信号15
这里是我的代码:
class ViewController: UIViewController {
@IBOutlet weak var myLabel: UILabel!
@IBOutlet weak var myButton: UIButton!
@IBOutlet weak var centerConstraint: NSLayoutConstraint!
@IBOutlet weak var viewBB: UIView!
@IBOutlet weak var lab2cxh: NSLayoutConstraint!
@IBOutlet weak var lab2cxv: NSLayoutConstraint!
@IBOutlet weak var label2: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// BLOCK 0 - works fine, from the iOS9 book
// myLabel and myButton were created with the interface builder
// Goal is to remove an IB constraint, and replace it with one
// that is built in code. (Because label and buttons are in
// different branches of the view hierarchy).
//
// remove auto center constraint from parent label
viewBB.removeConstraint(centerConstraint)
// center the label and the button across views
let ccx = NSLayoutConstraint(item: myLabel,
attribute: NSLayoutAttribute.CenterX,
relatedBy: NSLayoutRelation.Equal,
toItem: myButton,
attribute: NSLayoutAttribute.CenterX,
multiplier: 1.0,
constant: 0)
self.view.addConstraint(ccx)
// BLOCK 1 - Create a second label object in code
// this code works fine with the two added constraints below
// create a second label object and add it to the view
// let label2 = UILabel()
// label2.translatesAutoresizingMaskIntoConstraints = false
// label2.text="Label2"
// viewBB.addSubview(label2)
// BLOCK 2 - create a second label object in the interface builder
// Suggested horiz/vert constraints are set in the IB.
// So now I want to remove them, and replace them with my own,
// as was done in the Swift book example code in BLOCK 0.
// remove original label 2 constraints
viewBB.removeConstraint(lab2cxv)
viewBB.removeConstraint(lab2cxh)
// adding these two constraints works fine when the label2 object
// is created in code. But when I create label2 in the interface
// builder and try to remove the IB constraints (as was done in the
// first block of code), I get the error:
//
// ... "The view hierarchy is not prepared
// for the constraint "Label.CenterX to Button.CenterX", which is
// the first block of code.
//
// NOTE** To me, it looks like the error is coming from the
// BLOCK 0 constraint, since it cites a label and a button, not
// two labels.
// What am I doing wrong?
let c2h = NSLayoutConstraint(item: label2,
attribute: NSLayoutAttribute.CenterY,
relatedBy: NSLayoutRelation.Equal,
toItem: myLabel,
attribute: NSLayoutAttribute.CenterY,
multiplier: 1.0,
constant: -50)
self.viewBB.addConstraint(c2h)
// constrain label 2 to be diagonally left of label one
let c2v = NSLayoutConstraint(item: label2,
attribute: NSLayoutAttribute.CenterX,
relatedBy: NSLayoutRelation.Equal,
toItem: myLabel,
attribute: NSLayoutAttribute.CenterX,
multiplier: 1.0,
constant: -100)
self.viewBB.addConstraint(c2v)
}
尝试使用'ccx.active = true'而不是'self.view.addConstraint(ccx)'。并为您的物业使用更好的名称。 – dasdom
谢谢你回答我的问题。很抱歉地说,但建议的更改无效。这行代码是直接从书中出来的,并且在我添加下面的代码之前工作正常。 (授予,cx =约束,c =中心,cxv =约束垂直等对任何人都没有帮助。)是否有任何让视图层次结构没有准备的好列表,或者我可以学习和遵循的约定? Thx – Kevin
尝试将所有代码移出viewDidLoad并放入viewWillAppear。视图层次结构在viewDidLoad中没有完全建立。 – Michael