A bit of steroids for Auto Layout

Auto Layout is a constraint-based system that allows the creation of adaptive interfaces, making it easy to manage different screen sizes/orientations in your apps. What I like about Auto Layout, specially when doing it programmatically, is its expressiveness. You can look at the constraints and quickly understand what is going on with the views on the screen (or at least you should be able to!). It is also relatively easy and quick to add new constraints and integrate them with the existing ones.

At my current company, Insane Logic, all our UI is done programmatically using Auto Layout. While this gives us a huge flexibility and control, there’s also a downside: our constraint creation code is quite verbose. Swift can make it more readable when compared to Objective-C, but still it doesn’t make a huge difference. Recently I’ve been exploring possible ways to reduce some of the boilerplate when dealing with Auto Layout and, after analysing our typical code, several common patterns emerged:

  • When using Visual Format Language to create constraints, most of the times we don’t use a metrics array, and we don’t set any NSLayoutFormatOptions;
  • When adding a constraint to an item, most of the times we set the multiplier and constant values to 1 and 0, respectively;
  • We frequently center views in their parent/other views, and set the same constraint to multiple views;
  • It is common for “NSLayoutConstraint.constraintsWithVisualFormat” to be longer than the actual format string used!

With that in mind, I wrote a small library called AutoLayoutPlus consisting in a set of extensions to NSLayoutConstraint and UIView to makes things a little more manageable and simpler to work with. With AutoLayoutPlus you don’t need to change the way you’ve always worked with Auto Layout, it should feel as natural complement, offering the following features:

  • Complement the existing UIKit methods to create constraints for your views;
  • Helper methods for the most repetitive tasks (center view, apply the same constraint to multiple views, fill view horizontally, etc);
  • Default values for the arguments you usually don’t want to set;
  • Makes your code less verbose and easier to follow and maintain;
  • AutoLayoutPlus feels natural and provides a similar experience to the methods you are already familiar with.

Ok, but what does it look like?

Let me show you a couple of examples of how AutoLayoutPlus can be useful. Have a look at this code using Visual Format Language to set multiple constraints to a group of views:

NSLayoutConstraint.constraintsWithVisualFormat(“V:|[topContainer(==60)]”, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
NSLayoutConstraint.constraintsWithVisualFormat(“H:|[topContainer]|”, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
NSLayoutConstraint.constraintsWithVisualFormat(“V:[centerBlueContainer(==200)]”, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
NSLayoutConstraint.constraintsWithVisualFormat(“H:[centerBlueContainer(==100)]”, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
NSLayoutConstraint.constraintsWithVisualFormat(“V:[centerGreenContainer(==180)]”, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
NSLayoutConstraint.constraintsWithVisualFormat(“H:[centerGreenContainer(==80)]”, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
NSLayoutConstraint.constraintsWithVisualFormat(“V:[centerOrangeContainer(==160)]”, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
NSLayoutConstraint.constraintsWithVisualFormat(“H:[centerOrangeContainer(==60)]”, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)

Since we are not using any metrics array and not setting and NSLayoutFormatOptions, with AutoLayoutPlus it can be worked out to this:

NSLayoutConstraint.withFormat([
“V:|[topContainer(==60)]”,
“V:[centerBlueContainer(==200)]”,
“V:[centerGreenContainer(==180)]”,
“V:[centerOrangeContainer(==160)]”,
“V:[bottomContainer]|”,
“H:[centerBlueContainer(==100)]”,
“H:[centerGreenContainer(==80)]”,
“H:[centerOrangeContainer(==60)]”,
], views: views)

Let’s have a look at another one. In this case the same constraint is being applied to three different views:

NSLayoutConstraint(item: centerBlueContainer, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0)
NSLayoutConstraint(item: centerGreenContainer, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0)
NSLayoutConstraint(item: centerOrangeContainer, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0)

With AutoLayoutPlus it becomes easier to identify what is happening:

let viewsToCenter = [centerBlueContainer, centerGreenContainer, centerOrangeContainer]
NSLayoutConstraint.constraints(items: viewsToCenter, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY)

Handy, right?


This article gives a rough idea of what AutoLayoutPlus can offer. To see more examples take a look at the repository at https://github.com/ruipfcosta/AutoLayoutPlus, where you can also find a sample app.

If you have any questions get in touch on Twitter @ruipfcosta!

Like what you read? Give Rui Costa a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.