2014-09-21 2 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 질문은 대부분이 코코아 콩을 사용하고 있으며이를 피하려고합니다 또는 swift 대신 Obj-C을 사용하십시오. This 질문은 약간의 주제를 다루지 만 약간 낡은 질문입니다.신속한 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

고맙습니다 - 예를 들어 보았습니다. 과정을 잘 이해하지 못했습니다. –

3

거의 다 왔어. iOS Developer Library에 대한 참조

그러나
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-|" (동등 : 그냥 다음 코드를 ... ...

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

를 다음 줄을 교체 기본 여백에 대한 자세한 내용). 따라서 이러한 제약 조건은 레이블을 가운데 맞추기위한 것이 아닙니다. 실제로, viewController의 뷰에 8 개의 단위 상단, 끝 부분, 마침 및 마진이있는 막대한 레이블을 갖게됩니다.

무슨 뜻인지 확인하기 위해 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 버전에 대해 읽었습니다. 아직도이 물건을 배우기. –

+1

'addConstraints'와'addConstraint' 사이의 문법적으로 정확한 차이는별로 없어요. 피곤하면 좀 잡았다.' –

+0

매우 유용한 예입니다! – kennydust

관련 문제