Ios swift中的VFL约束:由于没有superview而崩溃

Ios swift中的VFL约束:由于没有superview而崩溃,ios,xcode,swift,visual-format-language,Ios,Xcode,Swift,Visual Format Language,我试图以编程的方式做一个简单的布局,但我想我遗漏了一些简单的东西,或者有些不合适的东西。以下ViewController应将标签居中放置在超级视图中。但是,它会因以下修剪消息而崩溃:视图层次结构未为约束做好准备。。。添加到视图时,约束项必须是该视图(或视图本身)的后代。如果在组装视图层次结构之前需要解决约束,则此操作将崩溃。。。在容器层次结构中找不到视图:。。。该视图的superview:NO superview另一个错误消息的问题大部分都使用NIB,我试图避免这种情况,或者使用Obj-C而不是

我试图以编程的方式做一个简单的布局,但我想我遗漏了一些简单的东西,或者有些不合适的东西。以下ViewController应将标签居中放置在超级视图中。但是,它会因以下修剪消息而崩溃:
视图层次结构未为约束做好准备。。。添加到视图时,约束项必须是该视图(或视图本身)的后代。如果在组装视图层次结构之前需要解决约束,则此操作将崩溃。。。在容器层次结构中找不到视图:。。。该视图的superview:NO superview
另一个错误消息的问题大部分都使用NIB,我试图避免这种情况,或者使用
Obj-C
而不是
swift
。这个问题有点涉及这个话题,但有点老了

谁能给我指出正确的方向吗

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()
}
}

这些约束在标签及其superview之间进行。约束应添加到该超级视图中,而不是添加到标签中

你就快到了。只需替换以下行

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
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:|-(>=10@750)-[label1]-(>=10@750)-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary))
}
然而,约束条件
H:|-[label1]-|“
V:|-[label1]-|”
等同于
H:|-8-[label1]-8-|“
V:|-8-[label1]-8-|”
(有关默认边距的更多详细信息,请参阅)。因此,这些约束并不意味着将标签居中。事实上,您将有一个巨大的标签,它有8个单位的顶部、前导、尾随和底部边距到viewController的视图

layoutView()
方法中添加以下代码行以了解我的意思:

label1.backgroundColor = UIColor.orangeColor()
可以,但如果您真的想将标签居中,则必须使用以下代码:

view.addConstraints(label1_H) // Comment these 2 lines and it runs, but
view.addConstraints(label1_V) // of course the label is upper left
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:|-(>=10@750)-[label1]-(>=10@750)-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary))
}

谢谢-我正在改编一个例子,但不太了解这个过程。谢谢,这也很有帮助。我一直在读关于添加约束的非
VFL
版本的书。还在学习这些东西。
addConstraints
addConstraints
虽然语法正确,但这两者之间的细微差别在我累的时候有点难理解`非常有用的例子!