4

So, I'm done using the IB in Xcode and want to write all UI in Swift.

So what I've done is:

  • Created a new UIView to contain the elements i want to write - lets call it "TestView"
  • I've added TestView to a VC as a sub view.
  • In the TestView class I've added the elements like this:

    class TestView: UIView {
          var someLabel:UILabel!
          override init(frame: CGRect) {
                super.init(frame: frame)
    
                self.someLabel = UILabel(frame: CGRect(x: self.frame.midX, y: oneSixthHeight, width: 100, height: 22))
                self.someLabel.text = "test"
    
                var constraints:[NSLayoutConstraint] = []
                self.someLabel.translatesAutoresizingMaskIntoConstraints = false
                let rightsideAnchor:NSLayoutConstraint = NSLayoutConstraint(item: self.someLabel, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1, constant: 1)
    
                 constraints.append(rightsideAnchor)
                 NSLayoutConstraint.activateConstraints(constraints)
          }
    }
    

With this I expect the UILabel to be anchored to the right side of the view.

However, I do get this error:

Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with items > and > because they have no common ancestor.
Does the constraint reference items in different view hierarchies? That's illegal.'

What am I doing wrong?

1
  • Where have you added someLabel as subview of your view ?? You can only apply constraints and activate them when they are already added as subview. trying otherwise will result in crash you just saw Commented Nov 28, 2016 at 8:35

2 Answers 2

9

You should add constraints only after view is added to the view hierarchy. From your code it is clear that you have not added the UILabel instance to view.

Sign up to request clarification or add additional context in comments.

1 Comment

THANK you! :) Added the label as subview and it all works like a charm. <3
8

Updated for Swift 3

import UIKit

class ViewController: UIViewController {

let redView: UIView = {

    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .red
    return view
}()

override func viewDidLoad() {
    super.viewDidLoad()

    setupViews()
    setupAutoLayout()
}

func setupViews() {

    view.backgroundColor = .white
    view.addSubview(redView)
}

func setupAutoLayout() {

    // Available from iOS 9 commonly known as Anchoring System for AutoLayout...
    redView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
    redView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20).isActive = true

    redView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    redView.heightAnchor.constraint(equalToConstant: 300).isActive = true

    // You can also modified above last two lines as follows by commenting above & uncommenting below lines...
    // redView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
    // redView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
 }
}

enter image description here

Type of Constraints:

/*
// regular use
1.leftAnchor
2.rightAnchor
3.topAnchor
// intermediate use
4.widthAnchor
5.heightAnchor
6.bottomAnchor
7.centerXAnchor
8.centerYAnchor
// rare use
9.leadingAnchor
10.trailingAnchor
etc. (note: very project to project)
*/

2 Comments

Thanks, always forgetting the "view.translatesAutoresizingMaskIntoConstraints = false"
9 and 10 should be used often as well, and should not be rare, especially for labels. Languages sometimes comes from right-to-left.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.