Beginning Auto Layout in iOS 6: Part 2/2
Update note: Check out our newer version of this tutorial, updated to Swift and iOS 8: Beginning Auto Layout Tutorial in Swift: Part 2. This tutorial is an abbreviated version of one of the chapters from our new book iOS 6 By Tutorials. Matthijs Hollemans wrote this – the same guy who wrote the iOS […] By Matthijs Hollemans.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Beginning Auto Layout in iOS 6: Part 2/2
35 mins
Fixing the width
The Pin menu has an option for Widths Equally. If you set this constraint on two views, then Auto Layout will always make both views equally wide, based on which one is the largest. Let’s play with that for a minute.
Select both buttons and choose Pin\Widths Equally. This adds a new constraint to both buttons:
Note: If you get an extra unintended constraint between one of the buttons and the superview, select the two buttons and select Align\Horizontal Centers again.
Note: If you get an extra unintended constraint between one of the buttons and the superview, select the two buttons and select Align\Horizontal Centers again.
You have seen this type of constraint before, in the first part of this tutorial. It looks like the usual T-bar but in the middle it has a circle with an equal sign.
In the Document Outline this shows up as a single Equal Widths constraint:
Changing the label text on one button will now change the size of the other one as well.
Change the bottom button’s label to “X”, just to make it really small. You will notice that the top button no longer fits its text:
So how does Interface Builder know which button’s size to use for both of them? If you pay close attention, you’ll see that a Width constraint was added to the button with the truncated text:
Interface Builder does this to force the button to become smaller than what it would ideally be, in order to comply with the Equal Widths constraint.
Obviously this is not what you want, so select the top button and choose Size to Fit Content from the Editor menu (or press Cmd =). Now the text fits inside the button again – or rather, the button fits around the text – and the Width constraint is gone.
Run the app and tap the buttons. The buttons always have the same width, regardless of which one has the largest label:
Of course, when both labels are very short, both buttons will shrink equally. After all, unless there is a constraint that prevents, buttons will size themselves to fit their content exactly, no more, no less. What was that called again? Right, the intrinsic content size.
Intrinsic Content Size
Before Auto Layout, you always had to tell buttons and other controls how big they should be, either by setting their frame or bounds properties or by resizing them in Interface Builder. But it turns out that most controls are perfectly capable of determining how much space they need, based on their content.
A label knows how wide and tall it is because it knows the length of the text that has been set on it, as well as the font size for that text. Likewise for a button, which might combine the text with a background image and some padding for the rounded corners.
The same is true for segmented controls, progress bars, and most other controls, although some may only have a predetermined height but an unknown width.
This is known as the intrinsic content size, and it is an important concept in Auto Layout. You have already seen it in action with the buttons. Auto Layout asks your controls how big they need to be and lays out the screen based on that information.
You can prevent this by setting an explicit Width or Height constraint on a control. If you resize the control by hand, then Interface Builder will set such an explicit constraint for you. With the Size to Fit Content command, you remove any fixed Width or Height constraints and let the control determine its intrinsic content size again.
Usually you want to use the intrinsic content size, but there are some cases where you may not want to do that. Imagine what happens when you set an image on a UIImageView if that image is much larger than the screen. You usually want to give image views a fixed width and height and scale the content, unless you want the view to resize to the dimensions of the image.
Intrinsic Content Size
Before Auto Layout, you always had to tell buttons and other controls how big they should be, either by setting their frame or bounds properties or by resizing them in Interface Builder. But it turns out that most controls are perfectly capable of determining how much space they need, based on their content.
A label knows how wide and tall it is because it knows the length of the text that has been set on it, as well as the font size for that text. Likewise for a button, which might combine the text with a background image and some padding for the rounded corners.
The same is true for segmented controls, progress bars, and most other controls, although some may only have a predetermined height but an unknown width.
This is known as the intrinsic content size, and it is an important concept in Auto Layout. You have already seen it in action with the buttons. Auto Layout asks your controls how big they need to be and lays out the screen based on that information.
You can prevent this by setting an explicit Width or Height constraint on a control. If you resize the control by hand, then Interface Builder will set such an explicit constraint for you. With the Size to Fit Content command, you remove any fixed Width or Height constraints and let the control determine its intrinsic content size again.
Usually you want to use the intrinsic content size, but there are some cases where you may not want to do that. Imagine what happens when you set an image on a UIImageView if that image is much larger than the screen. You usually want to give image views a fixed width and height and scale the content, unless you want the view to resize to the dimensions of the image.
So what happens when one of the buttons has a fixed Width constraint on it? Buttons calculate their own size, but you can override this by giving them a fixed width. Select the top button and choose Pin\Width from the menu. This adds a solid T-bar below the button:
Because this sort of constraint only applies to the button itself, not to its superview, it is listed in the Document Outline below the button object. In this case, you have fixed the button to a width of 73 points.
Run the app and tap the buttons. What happens? The button text does change, but it gets truncated because there is not enough room:
Because the top button has a fixed-width constraint and both buttons are required to be the same size, they will never shrink or grow.
Note: You probably wouldn’t set a Width constraint on a button by design – it is best to let the button use its intrinsic size – but if you ever run into a layout problem where you expect your controls to change size and they don’t, then double check to make sure Interface Builder didn’t sneak a fixed Width constraint in there.
Note: You probably wouldn’t set a Width constraint on a button by design – it is best to let the button use its intrinsic size – but if you ever run into a layout problem where you expect your controls to change size and they don’t, then double check to make sure Interface Builder didn’t sneak a fixed Width constraint in there.
Play around with this stuff for a bit to get the hang of pinning and aligning views. Get a feel for it, because not everything is immediately obvious. Just remember that there must always be enough constraints so that Auto Layout can determine the position and size for all views.