As you probably know, there are many articles that deal with AutoLayout. This wonderful tool from Apple solves the problem of developing for multiple screen sizes. It can be our best friend or our worst nightmare, depending on how much we know about it.
In this article we assume a basic knowledge of AutoLayout. This way we can jump right into more advanced concepts that currently lack clear documentation, such as:
Also, since Apple’s developers have been investing heavily in storyboards, this article is going to be focused on their use.
Do you remember when we had just one screen size? If you look back it was almost a dream… a dream that ended when the iPhone 5 came out. Where there used to be only autoresizing masks a new whole system appeared, triggering rejection among many developers due to its initial complexity.
I must say my thoughts were: “So it’s fine, iPhone 3.5/4 inches with autoresizing mask, iPad in another storyboard/xib or even in another project… I can live without AutoLayout. I don’t need to spend time on it”.
Things are completely different now. We have two new resolutions and it is no longer possible to create a responsive screen with a minimum quality that supports all possible screen sizes without using AutoLayout. But don’t worry, something that seems quite complex becomes easy if you know the base concepts that lie beneath it.
There are some articles that cover these base concepts in depth. For beginners I recommend this article:
If you want to get some deeper knowledge you can also check out:
After I read some articles and Apple’s official documentation I noticed there are some advanced concepts that are not fully explained. I am writing this article as if it was going to be read by me 1 year ago. Hopefully it can help other developers that find themselves in this position now.
First of all, let’s take a look at the different sections of the Size Inspector:
Frame Rectangle: Displays the raw frame.
Alignment Rectangle: Includes possible area around the view.
Allthe constraints or just the ones related with
This Size Class. If you want to learn more about size classes I recommend that you read Begining with Size Classes.
Content Hugging Priority:
Here is where the view’s resistance to being stretched is defined.
Content Compression Resistance Priority:
Here is where the view’s resistance to being compressed is defined.
Default (System Defined) is the default selection but if we choose
Placeholder we can define the frame of the view.
We will take a deeper look on these concepts by approaching them from a practical point of view. In order to do so we must learn more about what is
constrait priority and how it works.
Constraints can be assigned priorities that define which one is stronger. E.g. a constraint with a priority of 750 will prevail over one of 500. Let’s use an example to illustrate this. If we have the following constraints defined on the centered subview:
Center Xhave a priority of 1000.
Top space<= 70 has a priority of 1000.
Center Yhas a priority of 750.
Note: Every constraint with priority < 1000 will be represented using a dashed line.
Our goal is that on smaller screens (3.5 inches for instance) the view stays in the center because of the third constraint and the top space is less than 70 points. So every constraint is satisfied. But what happens in case the screen is big enough to make the space at the top bigger than 70 points and break the third constraint? Nothing, because the first constraint has a higher priority so the view will stay at 70 points from the top.
Let’s say we change the priority of the third constraint to 1000. In this scenario, if one of the two constraints cannot be satisfied because the size of the screen is too big, we will see an error saying we should delete at least one of the constraints. This is because the system cannot decide which one to use.
Looking into UIKit/NSLayoutConstraint.h header we will find 4 macros to define a constraint priority programatically:
Now that we covered about content compression resistance and content hugging priorities, it is time to explain them in more detail. But first let’s quickly introduce another important concept.
This is the minimum size an interface element has by default.
UIKit elements such as UILabel or UIButton implement their intrinsic size based on their content, such as a title or icon. Other UIKit elements, such as UIView, which do not have such a defined content don’t implement this method. When we use them in a storyboard or xib we should define their sizes.
If we know the size our custom view should have we can define it programatically in our custom subclass. Unfortunately, storyboards don’t recognize this so we must define it in the
Intrinsic Size section as a
In case the element we are using doesn’t implement
intrinsicContentSize (or inherits from a class that does) we have to include constraints that define the view’s width and height explicitly.
This is how resistant the view is to becoming smaller than its intrinsic content size. The way I see this is like a width or height constraint with params:
In order to explain it better we are going to use an example. Let’s say we have a UIButton with default content compression resistance priority (=750) and we set a new width constraint:
Since the priority is less than the Content Compression Resistance Priority the button will maintain a width of 46 points.
But what if we change the priority from 500 to 1000? In this case it will be stronger than the Content Compression Resistance and the button will be compressed and display “…".
This concept is quite similar to the previous one. It defines how resistant the view is to becoming larger than its intrinsic content size. A constraint should have the form:
Let’s use another example with a similar constraint to better understand it:
This time the view will expand up to 120 points of width because the constraint has a higher priority than the Content Hugging. If we want the view to keep a width of 46 points we should make the constraint priority lower than the Content Hugging Priority.
I must admit that when I first tried AutoLayout I didn’t like it at all. It was very powerful but at the same time so complicated that I decided to keep using autoresizing masks for everything. AutoLayout was just the checkbox I unchecked everytime I created a new storyboard or xib.
I realize now I wasn’t very wise, but better late than never! Also, the AutoLayout system has been continually improving and today it is much easier than ever before. I think all the time spent learning how AutoLayout works is worth it. I hope this post helps you to understand a little bit better how this system works and how to use it to create fully adaptative views.