Atelier Clockwork

Autolayout Sanity

Not Quite Mastery, but Starting to Get a Real Handle on Things

After rebuilding a very complex view hierarchy that’s full of state, I’m starting to have complex layout blocks that look right, and don’t throw any constraint failures on the first try. As I start to feel like I understand how to work with Autolayout, I’m starting to understand why it’s non-intuitive.

Some of the lessons learned this week are:

Priority Doom

One of the largest mistakes that I made was trying to set constraints to UILayoutPriorityRequired, or more often than not using helper methods creating required constraints. The problem with required is, the instant that constraint can’t be met, it wants to break. And of course, this can affect the layout of surround views, intrinsic sizes, etc.

Lie to the Layout Engine

Controlling which views expand to fit and which maintain their intrinsic size can be a bit of a headache in a complex dynamic layout. One trick that I’ve found useful is to set a zero size constraint on a view with a priority below UILayoutPriorityFittingSizeLevel. The intrinsic size of the view overrides the zero size, but it helps keep the view from expanding to fit a larger volume when sharing space with a different view.

Sketch and Plan

Adding new rules to a working system of constraints often breaks things, so make sure you’re not going to be one rule short of working correctly when someone else reviews the results. Plan for hairline views, padding, etc as much as possible.

Think in Stacks

Whenever possible, I’ve started applying constraints using iteration over arrays of views that will be in stacks. This means adding a new view to the stack or re-ordering shouldn’t require new code, and it dramatically reduces the length of many of the creation methods.

Keep it Consistent

Pick rules about where constraints are created, how they’re managed, and when they’re updated and stick to them. The more places you’re writing constraints that affect a view, the more likely it is that you’ll be debugging in the wrong place.