Ios 未准备视图层次结构
我是一个新手swift开发人员,下面是一本很好的iOS9SWIFT书籍中的代码示例。本书刚刚演示了如何在视图层次的两个不同分支中的两个对象(标签、按钮)之间添加约束(在代码中) myLabel位于viewBB容器中,该容器位于俯视图控制器中。 myButton位于俯视图控制器中,在viewBB之外 示例代码运行良好。但作为练习,我想在viewBB内部创建第二个label2,并将其位置约束为与myLabel偏移。所以这两个标签(我想)都在viewBB中 在代码中创建label2并在代码中添加约束效果良好 但是。。。如果我在interface builder中创建label2,并尝试删除IB约束并用我自己的约束替换它们,则构建成功,但应用程序崩溃,出现通常的“视图层次结构未准备好”错误 ***有趣的是,错误消息谈到了一个标签和一个按钮,表明图书示例代码(我在下面称它为BLOCK 0)就是违规者 我做错了什么?(我已经阅读了错误信息中的所有内容,包括本论坛中的4篇帖子。但是我不知道为什么书的代码会失败。) 错误消息: 2016-02-25 12:52:32.796两个视图约束[5713:1860768] 未为约束准备视图层次结构:NSLayoutConstraint:0x7c9ce990 UILabel:0x7c9dbec0'Label'。centerX== UI按钮:0x7c9deed0“按钮”。centerX 添加到视图时,约束项必须是该视图(或视图本身)的后代。如果在装配视图层次之前需要解决约束,则此操作将崩溃。中断-[UIView(UIConstraintBasedLayout)\u viewHierarchyUnpreparedForConstraint:]以进行调试 来自调试器的消息:由于信号15而终止 这是我的密码:Ios 未准备视图层次结构,ios,swift,Ios,Swift,我是一个新手swift开发人员,下面是一本很好的iOS9SWIFT书籍中的代码示例。本书刚刚演示了如何在视图层次的两个不同分支中的两个对象(标签、按钮)之间添加约束(在代码中) myLabel位于viewBB容器中,该容器位于俯视图控制器中。 myButton位于俯视图控制器中,在viewBB之外 示例代码运行良好。但作为练习,我想在viewBB内部创建第二个label2,并将其位置约束为与myLabel偏移。所以这两个标签(我想)都在viewBB中 在代码中创建label2并在代码中添加约束效
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)
}
我从头开始重新编写了整段代码,它成功了。仔细想想,这是正确运行的代码。就我所见,它几乎是相同的代码,只是在这里和那里有一个小的名称更改 我不知道为什么这个版本有效,而上一个版本没有。这让我想知道Interface Builder的设置是否有所不同
class ViewController: UIViewController {
@IBOutlet weak var viewbb: UIView!
@IBOutlet weak var myLabel: UILabel!
@IBOutlet weak var centerConstraint: NSLayoutConstraint!
@IBOutlet weak var myButton: UIButton!
@IBOutlet weak var label2: UILabel!
@IBOutlet weak var label2centerConstraint: NSLayoutConstraint!
@IBOutlet weak var label2Yconstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// remove the IB centering constraint, then add our own between label and button
viewbb.removeConstraint(centerConstraint)
// make a new constraint to center label over button
let newcon = NSLayoutConstraint(item: myLabel,
attribute: NSLayoutAttribute.CenterX,
relatedBy: NSLayoutRelation.Equal,
toItem: myButton,
attribute: NSLayoutAttribute.CenterX,
multiplier: 1.0,
constant: 0)
self.view.addConstraint(newcon)
// remove the IB centering constraint, then add our own between label and button
viewbb.removeConstraint(label2centerConstraint)
viewbb.removeConstraint(label2Yconstraint)
// make a new constraint to center label over button
let newcon2 = NSLayoutConstraint(item: label2,
attribute: NSLayoutAttribute.CenterX,
relatedBy: NSLayoutRelation.Equal,
toItem: myLabel,
attribute: NSLayoutAttribute.CenterX,
multiplier: 1.0,
constant: -100) // left of mylabel
// make a new constraint to center label over button
let newcon3 = NSLayoutConstraint(item: label2,
attribute: NSLayoutAttribute.CenterY,
relatedBy: NSLayoutRelation.Equal,
toItem: myLabel,
attribute: NSLayoutAttribute.CenterY,
multiplier: 1.0,
constant: 0) // left of mylabel
self.view.addConstraint(newcon3)
self.view.addConstraint(newcon2)
}
尝试使用
ccx.active=true
而不是self.view.addConstraint(ccx)
。并为您的财产使用更好的名称。谢谢您回答我的问题。很抱歉,建议的更改无效。这行代码是直接从书中写出来的,在我将代码添加到下面之前,它工作得很好。(当然,cx=constraint、c=center、cxv=constraint-vertical等对任何人都没有多大帮助。)是否有什么让视图层次结构毫无准备的好的列表,或者我可以研究和遵循的约定?将所有代码移出viewDidLoad并移入VIEW将显示。视图层次结构在viewDidLoad中没有完全建立。我还尝试将两个新的约束添加到self.viewbb而不是self.view,但没有什么不同。代码仍然运行良好。(回想一下,viewbb是父顶级视图中的视图容器。viewbb容器包含两个标签视图,因此新约束可以放置在直接父视图(viewbb)或顶级视图(self.view)中。