Autolayout is wordy, full of edge cases, and hard to work with. This is compounded by trait collections and the proliferation of device sizes. A complex view state can take hundreds of lines to define using the standard methods in
Building constraints visually in Interface Builder can be slightly easier, and you get something of a visual representation, but it still is less than perfect.
There’s also the problem of building impossible to satisfy constraints that work conceptually, and that bad constraints generate large amounts of console noise.
The Short Term Solution
First I tried hacking my own engine to destroy and rebuild the view layout whenever the view chanted trait collections. This ended with very broken view state because I was just a bit overzealous in removing constraints with helper methods.
After sleeping on that approach, I switched to a heavily nested approach with subviews representing rows and columns. This let me cut down the constraint creation code by about half, ended up with a view hierarchy that made sense, and more importantly, it worked. It now potentially needs to add animations for transitions, and need some polish, but I learned a lot about working with Autolayout.
The Long Term Solution
Really this requires two parts. The first part will be to find a better domain specific language for creating constraints. My front runner to look into is Masonry or AutolayoutKit. I could try building one from scratch, but I’d rather try other options first and save myself some of the more fun learning experiences.
The second step is going to be trying to build a formal process for designing the view layout. A big part of the problem I ran into was trying to shove too many things into one view. I think a lot of time could be saved by decomposing the objects in a view into blocks and defining the different configurations before trying to code anything.