Programmatically Add CenterX/CenterY Constraints Programmatically Add CenterX/CenterY Constraints ios ios

Programmatically Add CenterX/CenterY Constraints


Update for Swift 3/Swift 4:

As of iOS 8, you can and should activate your constraints by setting their isActive property to true. This enables the constraints to add themselves to the proper views. You can activate multiple constraints at once by passing an array containing the constraints to NSLayoutConstraint.activate()

let label = UILabel(frame: CGRect.zero)label.text = "Nothing to show"label.textAlignment = .centerlabel.backgroundColor = .red  // Set background color to see if label is centeredlabel.translatesAutoresizingMaskIntoConstraints = falseself.tableView.addSubview(label)let widthConstraint = NSLayoutConstraint(item: label, attribute: .width, relatedBy: .equal,                                         toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 250)let heightConstraint = NSLayoutConstraint(item: label, attribute: .height, relatedBy: .equal,                                          toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 100)let xConstraint = NSLayoutConstraint(item: label, attribute: .centerX, relatedBy: .equal, toItem: self.tableView, attribute: .centerX, multiplier: 1, constant: 0)let yConstraint = NSLayoutConstraint(item: label, attribute: .centerY, relatedBy: .equal, toItem: self.tableView, attribute: .centerY, multiplier: 1, constant: 0)NSLayoutConstraint.activate([widthConstraint, heightConstraint, xConstraint, yConstraint])

Better Solution:

Since this question was originally answered, layout anchors were introduced making it much easier to create the constraints. In this example I create the constraints and immediately activate them:

label.widthAnchor.constraint(equalToConstant: 250).isActive = truelabel.heightAnchor.constraint(equalToConstant: 100).isActive = truelabel.centerXAnchor.constraint(equalTo: self.tableView.centerXAnchor).isActive = truelabel.centerYAnchor.constraint(equalTo: self.tableView.centerYAnchor).isActive = true

or the same using NSLayoutConstraint.activate():

NSLayoutConstraint.activate([    label.widthAnchor.constraint(equalToConstant: 250),    label.heightAnchor.constraint(equalToConstant: 100),    label.centerXAnchor.constraint(equalTo: self.tableView.centerXAnchor),    label.centerYAnchor.constraint(equalTo: self.tableView.centerYAnchor)])

Note: Always add your subviews to the view hierarchy before creating and activating the constraints.


Original Answer:

The constraints make reference to self.tableView. Since you are adding the label as a subview of self.tableView, the constraints need to be added to the "common ancestor":

   self.tableView.addConstraint(xConstraint)   self.tableView.addConstraint(yConstraint)

As @mustafa and @kcstricks pointed out in the comments, you need to set label.translatesAutoresizingMaskIntoConstraints to false. When you do this, you also need to specify the width and height of the label with constraints because the frame no longer is used. Finally, you also should set the textAlignment to .Center so that your text is centered in your label.

    var  label = UILabel(frame: CGRectZero)    label.text = "Nothing to show"    label.textAlignment = .Center    label.backgroundColor = UIColor.redColor()  // Set background color to see if label is centered    label.translatesAutoresizingMaskIntoConstraints = false    self.tableView.addSubview(label)    let widthConstraint = NSLayoutConstraint(item: label, attribute: .Width, relatedBy: .Equal,        toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 250)    label.addConstraint(widthConstraint)    let heightConstraint = NSLayoutConstraint(item: label, attribute: .Height, relatedBy: .Equal,        toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 100)    label.addConstraint(heightConstraint)    let xConstraint = NSLayoutConstraint(item: label, attribute: .CenterX, relatedBy: .Equal, toItem: self.tableView, attribute: .CenterX, multiplier: 1, constant: 0)    let yConstraint = NSLayoutConstraint(item: label, attribute: .CenterY, relatedBy: .Equal, toItem: self.tableView, attribute: .CenterY, multiplier: 1, constant: 0)    self.tableView.addConstraint(xConstraint)    self.tableView.addConstraint(yConstraint)


Center in container

enter image description here

The code below does the same thing as centering in the Interface Builder.

override func viewDidLoad() {    super.viewDidLoad()    // set up the view    let myView = UIView()    myView.backgroundColor = UIColor.blue    myView.translatesAutoresizingMaskIntoConstraints = false    view.addSubview(myView)    // Add code for one of the constraint methods below    // ...}

Method 1: Anchor Style

myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = truemyView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

Method 2: NSLayoutConstraint Style

NSLayoutConstraint(item: myView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0).isActive = trueNSLayoutConstraint(item: myView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0).isActive = true

Notes

  • Anchor style is the preferred method over NSLayoutConstraint Style, however it is only available from iOS 9, so if you are supporting iOS 8 then you should still use NSLayoutConstraint Style.
  • You will also need to add length and width constraints.
  • My full answer is here.


The ObjectiveC equivalent is:

    myView.translatesAutoresizingMaskIntoConstraints = NO;    [[myView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor] setActive:YES];    [[myView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor] setActive:YES];