How to add constraints programmatically using Swift How to add constraints programmatically using Swift ios ios

How to add constraints programmatically using Swift


Do you plan to have a squared UIView of width: 100 and Height: 100 centered inside the UIView of an UIViewController? If so, you may try one of the 6 following Auto Layout styles (Swift 5 / iOS 12.2):


1. Using NSLayoutConstraint initializer

override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)    newView.translatesAutoresizingMaskIntoConstraints = false    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)    let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0)    let widthConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100)    let heightConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100)    view.addConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])}
override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)    newView.translatesAutoresizingMaskIntoConstraints = false    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)    let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0)    let widthConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100)    let heightConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100)    NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])}
override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)    newView.translatesAutoresizingMaskIntoConstraints = false    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0).isActive = true    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0).isActive = true    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100).isActive = true    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100).isActive = true}

2. Using Visual Format Language

override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)    newView.translatesAutoresizingMaskIntoConstraints = false    let views = ["view": view!, "newView": newView]    let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[view]-(<=0)-[newView(100)]", options: NSLayoutConstraint.FormatOptions.alignAllCenterY, metrics: nil, views: views)    let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[view]-(<=0)-[newView(100)]", options: NSLayoutConstraint.FormatOptions.alignAllCenterX, metrics: nil, views: views)    view.addConstraints(horizontalConstraints)    view.addConstraints(verticalConstraints)}
override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)    newView.translatesAutoresizingMaskIntoConstraints = false    let views = ["view": view!, "newView": newView]    let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[view]-(<=0)-[newView(100)]", options: NSLayoutConstraint.FormatOptions.alignAllCenterY, metrics: nil, views: views)    let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[view]-(<=0)-[newView(100)]", options: NSLayoutConstraint.FormatOptions.alignAllCenterX, metrics: nil, views: views)    NSLayoutConstraint.activate(horizontalConstraints)    NSLayoutConstraint.activate(verticalConstraints)}

3. Using a mix of NSLayoutConstraint initializer and Visual Format Language

override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)    newView.translatesAutoresizingMaskIntoConstraints = false    let views = ["newView": newView]    let widthConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)    let heightConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)    let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0)    view.addConstraints(widthConstraints)    view.addConstraints(heightConstraints)    view.addConstraints([horizontalConstraint, verticalConstraint])}
override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)    newView.translatesAutoresizingMaskIntoConstraints = false    let views = ["newView": newView]    let widthConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)    let heightConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)    let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0)    NSLayoutConstraint.activate(widthConstraints)    NSLayoutConstraint.activate(heightConstraints)    NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])}
override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)    newView.translatesAutoresizingMaskIntoConstraints = false    let views = ["newView": newView]    let widthConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)    let heightConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[newView(100)]", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views)    NSLayoutConstraint.activate(widthConstraints)    NSLayoutConstraint.activate(heightConstraints)    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0).isActive = true    NSLayoutConstraint(item: newView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0).isActive = true}

4. Using UIView.AutoresizingMask

Note: Springs and Struts will be translated into corresponding auto layout constraints at runtime.

override func viewDidLoad() {    let newView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))    newView.backgroundColor = UIColor.red    view.addSubview(newView)    newView.translatesAutoresizingMaskIntoConstraints = true    newView.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)    newView.autoresizingMask = [UIView.AutoresizingMask.flexibleLeftMargin, UIView.AutoresizingMask.flexibleRightMargin, UIView.AutoresizingMask.flexibleTopMargin, UIView.AutoresizingMask.flexibleBottomMargin]}

5. Using NSLayoutAnchor

override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)        newView.translatesAutoresizingMaskIntoConstraints = false    let horizontalConstraint = newView.centerXAnchor.constraint(equalTo: view.centerXAnchor)    let verticalConstraint = newView.centerYAnchor.constraint(equalTo: view.centerYAnchor)    let widthConstraint = newView.widthAnchor.constraint(equalToConstant: 100)    let heightConstraint = newView.heightAnchor.constraint(equalToConstant: 100)    view.addConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])}
override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)        newView.translatesAutoresizingMaskIntoConstraints = false    let horizontalConstraint = newView.centerXAnchor.constraint(equalTo: view.centerXAnchor)    let verticalConstraint = newView.centerYAnchor.constraint(equalTo: view.centerYAnchor)    let widthConstraint = newView.widthAnchor.constraint(equalToConstant: 100)    let heightConstraint = newView.heightAnchor.constraint(equalToConstant: 100)    NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])}
override func viewDidLoad() {    let newView = UIView()    newView.backgroundColor = UIColor.red    view.addSubview(newView)        newView.translatesAutoresizingMaskIntoConstraints = false    newView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true    newView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true    newView.widthAnchor.constraint(equalToConstant: 100).isActive = true    newView.heightAnchor.constraint(equalToConstant: 100).isActive = true}

6. Using intrinsicContentSize and NSLayoutAnchor

import UIKitclass CustomView: UIView {        override var intrinsicContentSize: CGSize {        return CGSize(width: 100, height: 100)    }    }class ViewController: UIViewController {        override func viewDidLoad() {        let newView = CustomView()        newView.backgroundColor = UIColor.red        view.addSubview(newView)                newView.translatesAutoresizingMaskIntoConstraints = false        let horizontalConstraint = newView.centerXAnchor.constraint(equalTo: view.centerXAnchor)        let verticalConstraint = newView.centerYAnchor.constraint(equalTo: view.centerYAnchor)        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])    }    }

Result:

enter image description here


It helps me to learn visually, so this is a supplemental answer.

Boilerplate code

override func viewDidLoad() {    super.viewDidLoad()    let myView = UIView()    myView.backgroundColor = UIColor.blue    myView.translatesAutoresizingMaskIntoConstraints = false    view.addSubview(myView)    // Add constraints code here    // ...}

Each of the following examples are independent of the others.

Pin left edge

myView.leading = leadingMargin + 20

enter image description here

Method 1: Anchor Style

let margins = view.layoutMarginsGuidemyView.leadingAnchor.constraint(equalTo: margins.leadingAnchor, constant: 20).isActive = true
  • In addition to leadingAnchor, there is also trailingAnchor, topAnchor, and bottomAnchor.

Method 2: NSLayoutConstraint Style

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.leadingMargin, multiplier: 1.0, constant: 20.0).isActive = true
  • In addition to .leading there is also .trailing, .top, and .bottom.
  • In addition to .leadingMargin there is also .trailingMargin, .topMargin, and .bottomMargin.

Set Width and Height

width = 200
height = 100

enter image description here

Method 1: Anchor Style

myView.widthAnchor.constraint(equalToConstant: 200).isActive = truemyView.heightAnchor.constraint(equalToConstant: 100).isActive = true

Method 2: NSLayoutConstraint Style

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 200).isActive = trueNSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100).isActive = true

Center in container

myView.centerX = centerX
myView.centerY = centerY

enter image description here

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: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0).isActive = trueNSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.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.
  • The examples above showed just the one or two constraints that were being focused on. However, in order to properly place myView in my test project I needed to have four constraints.

Further Reading


If you want to fill your super view then I suggest the swifty way:

    view.translatesAutoresizingMaskIntoConstraints = false    let attributes: [NSLayoutAttribute] = [.top, .bottom, .right, .left]    NSLayoutConstraint.activate(attributes.map {        NSLayoutConstraint(item: view, attribute: $0, relatedBy: .equal, toItem: view.superview, attribute: $0, multiplier: 1, constant: 0)    })

Other wise if you need non equal constraints check out NSLayoutAnchor as of iOS 9. Its often much easier to read that using NSLayoutConstraint directly:

    view.translatesAutoresizingMaskIntoConstraints = false    view.topAnchor.constraint(equalTo: view.superview!.topAnchor).isActive = true    view.bottomAnchor.constraint(equalTo: view.superview!.bottomAnchor).isActive = true    view.leadingAnchor.constraint(equalTo: view.superview!.leadingAnchor, constant: 10).isActive = true    view.trailingAnchor.constraint(equalTo: view.superview!.trailingAnchor, constant: 10).isActive = true