I haven't had much time to spend with Swift lately but with the release of Swift 1.2 it seemed like a good time to refresh my memory. I have one (very unfinished) project written entirely in Swift that helps me keep track of the changes in the language. This project has come to the point where I can no longer rely on storyboards and nibs for layout so the time had come to look seriously at writing Auto Layout code in Swift.
Now I know there are a few open source libraries that provide convenience methods and/or DSLs for working with Auto Layout in both Swift and Objective C and I'm sure they're mostly brilliant. Regardless, I like to really understand the code I'm writing and as a rule I avoid any library I can write (the subset I require of) myself.
So what are the most common things we need to do when laying out views? This is roughly what I came up with:
- Place a view within a parent pinned relative to the parent (Struts!)
- Place a view within a parent pinned to opposite edges so that it resizes with the parent (Springs!)
- Set the explicit width and or height of a view
- Set the relative width and or height of a view based on a another view
- Place a view relative to another view in the hierarchy
- Align a view with another view within the hierarchy
NSLayoutConstraint can do all of this (and a lot more) but this seemed to me to be the low hanging fruit, as it were, for simplifying layout code. So with these requirements in mind, and a goal of simplicity and readability above all else
You might notice that while only one of the functions returns more than one constraint they all return an array. At this point I feel like consistency is more important that any performance hit this may cause but without knowing that much about how Swift allocates arrays and without any real-world benchmarking it's hard to tell. I figure it's very likely I may want to add new functions in the future that return multiple constraints and in my experience constraints are usually built up by combining multiple arrays anyway. Regardless, that's less than 100 lines of code, you can can probably understand most of it it in glance and it makes for some relatively concise and readable layout code:
Which results, roughly, in the first of this article(figure 1 Swift Layout). I think that's a pretty big win for a wafer-thin level of abstraction.