Topics

#98: Auto Layout in Code 📐📏

Topics

Auto Layout works great in Interface Builder, but it's often helpful to have the flexibility and clarity of wiring up constraints in code. Let's dive in.

We'll add a view and set translatesAutoresizingMaskIntoConstraints to false. Normally Interface Builder does this automatically under the hood, but since we're working in code we'll need to set it ourselves. Don't want any funky autoresizing constraints in there meddling around.

let logo = UIView()

logo.translatesAutoresizingMaskIntoConstraints = false

container.addSubview(logo)

When learning to work with Auto Layout in code, it can be helpful to remember that constraints are essentially just linear equations:

viewA.property = multiplier * viewB.property + constant

To express centering a view inside it's superview, we could write it as:

view.center.x = 1.0 * superview.center.x + 0.0
view.center.y = 1.0 * superview.center.y + 0.0

Let's look at how to express the same thing (centering our logo view inside it's superview) using NSLayoutConstraint objects in code:

container.addConstraints([
  NSLayoutConstraint(item: logo, attribute: .CenterX, relatedBy: .Equal, toItem: container, attribute: .CenterX, multiplier: 1, constant: 0),
  NSLayoutConstraint(item: logo, attribute: .CenterY, relatedBy: .Equal, toItem: container, attribute: .CenterY, multiplier: 1, constant: 0)
])

Whew! That's a long constructor. The neat part though, is from left-to-right it almost reads like the equations from before. Lastly, we'll assign a fixed size to our logo view. Since there's only 1 view involved, the equation is much simpler:

view.height = 0.0 * nothing + constant.

And finally, in code this looks like:

container.addConstraints([
  NSLayoutConstraint(item: logo, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 115),
  NSLayoutConstraint(item: logo, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 70)
])