2014-09-21 27 views
2

我正在尝试以编程方式进行简单的布局,并且我错过了一些简单的事情,或者有一些不合适的地方,我想。以下ViewController应该将标签置于超级视图中。然而,它与这个修剪消息崩溃:The view hierarchy is not prepared for the constraint ... When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled... View not found in container hierarchy: ... That view's superview: NO SUPERVIEW其他SO问题与此错误消息大部分使用笔尖,我想要避免,或使用Obj-C而不是swiftThis问题处理这个话题有点但有点老了。swift中的VFL约束:由于没有超级视图导致的崩溃

任何人都可以指向正确的方向吗?

class ViewController: UIViewController { 
let label1 = UILabel() as UILabel 

func layoutView(){ 

    label1.text = "Click to see device configuration" 
    label1.setTranslatesAutoresizingMaskIntoConstraints(false) 
    view.addSubview(label1) 
    let viewsDictionary = ["label1":label1] 

    let label1_H:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[label1]-|", 
     options: NSLayoutFormatOptions(0), 
     metrics: nil, 
     views: viewsDictionary) 

    let label1_V:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("V:|-[label1]-|", 
     options: NSLayoutFormatOptions(0), 
     metrics: nil, views: 
     viewsDictionary) 

    label1.addConstraints(label1_H) // Comment these 2 lines and it runs, but 
    label1.addConstraints(label1_V) // of course the label is upper left 

} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    layoutView() 
} 
} 

回答

4

这些约束是在标签和它的超级视图之间进行的。约束条件应该添加到超级视图中,而不是标签。

+0

谢谢 - 我正在调整一个例子,并不完全理解这个过程。 – 2014-09-22 00:12:38

3

你快到了。只需用下面的代码替换下面的行...

label1.addConstraints(label1_H) // Comment these 2 lines and it runs, but 
label1.addConstraints(label1_V) // of course the label is upper left 

...:

view.addConstraints(label1_H) // Comment these 2 lines and it runs, but 
view.addConstraints(label1_V) // of course the label is upper left 

然而,约束H:|-[label1]-|"V:|-[label1]-|"相当于H:|-8-[label1]-8-|"V:|-8-[label1]-8-|"(见iOS Developer Library为有关默认边距的更多详细信息)。因此,这些限制并不意味着以您的标签为中心。实际上,您只需拥有一个巨大的标签,该标签具有8个单元顶部,前导,尾部和底部边距到viewController的视图。

添加下面的代码行放在layoutView()方法明白我的意思:

label1.backgroundColor = UIColor.orangeColor() 

它可以是确定的,但如果你真的要居中你的标签,你将不得不使用以下代码:

func layoutView() { 
    label1.text = "Click to see device configuration" 
    label1.backgroundColor = UIColor.orangeColor() 
    //Set number of lines of label1 to more than one if necessary (prevent long text from being truncated) 
    label1.numberOfLines = 0 

    label1.setTranslatesAutoresizingMaskIntoConstraints(false) 
    view.addSubview(label1) 

    let xConstraint = NSLayoutConstraint(item: label1, 
     attribute: NSLayoutAttribute.CenterX, 
     relatedBy: NSLayoutRelation.Equal, 
     toItem: view, 
     attribute: NSLayoutAttribute.CenterX, 
     multiplier: 1.0, 
     constant: 0.0) 
    self.view.addConstraint(xConstraint) 

    let yConstraint = NSLayoutConstraint(item: label1, 
     attribute: NSLayoutAttribute.CenterY, 
     relatedBy: NSLayoutRelation.Equal, 
     toItem: view, 
     attribute: NSLayoutAttribute.CenterY, 
     multiplier: 1.0, 
     constant: 0) 
    self.view.addConstraint(yConstraint) 

    //Add leading and trailing margins if necessary (prevent long text content in label1 to be larger than screen) 
    let viewsDictionary = ["label1" : label1] 
    view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-(>[email protected])-[label1]-(>[email protected])-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)) 
} 
+0

谢谢,这也非常有帮助。我一直在阅读有关添加约束的非'VFL'版本。仍在学习这些东西。 – 2014-09-22 01:08:24

+1

'addConstraints'和'addConstraint'虽然语法上正确,但是当我累了时,有一点点不同' – 2014-09-22 01:22:27

+0

非常有帮助的例子! – kennydust 2015-07-14 04:25:07

相关问题