iOS and iPadOS Auto Layout are great. It helps build universal, good-looking apps for both screen sizes, provides a way to support portrait and landscape orientations without hassle.
On rare occasions, it behaves strangely. Because of its powerful and easy-to-use features, there are some corner cases that we, as iOS devs, should know.
Imagine this, you are developing a screen for iPhone and iPad. Table view cell content on a smaller screen has leading 16 points, on a bigger screen - 144 points. Easy one, create constraints in Xib/Storyboard and make variants for different sizes:
It works! You test it on devices, the layout looks great! Problem solved:)
The requirements change
Inevitable, requirements change is around the corner. Now our view should have 16 points padding on iPhone, 144 on iPad, but 16 points for iPad split view.
Looks easy, make an outlet for constraint, and if the cells view model says it should have a padding of 16 points, just set constraint's constant to the new value. Let's test the code. It doesn't work! How it is possible, I'm setting the constant to 16 but it is still 144 when the screen is presented!
This is where traits collections come to play. If you are setting constraint constant, and it has variants for sizes, you have to do it after traitCollectionDidChange
. When trait collection is changed, the Auto Layout engine checks if there is a variant for a new trait and sets it overwriting your value. To make it work as expected, you need to override traitCollectionDidChange
and put code after the call to super
.
There is another method, if your setup allows it, Apple gives the option to override trait collection for child view controller: setOverrideTraitCollection(_:forChild:)
, remember, this will set a new value for all the views inside the child view controller, so be warned. Use responsibly.
I hope this piece will give you a glimpse of Auto Layout quirks and features:)