Auto Layout is a powerful constraint-based layout engine that can drive complex and dynamic interfaces on both iOS and OS X. Learn about the new UIStackView, now your first stop for interfaces built with Auto Layout. See how to build self-sizing views using Auto Layout, and gain critical insights into the inner workings of Auto Layout.
My name is Jason Yao.
I am an interface builder engineer.
I am going to be presenting with Kasia, an iOS keyboard engineer.
Welcome to the Mysteries of Auto Layout.
As developers, you want to build bold and beautiful apps
that will surprise and delight your customers.
Having a great layout will put your app ahead,
and your customers will reward you for it.
Having to target all the different devices
and configurations as well as multitasking
and localization can be a challenge.
Luckily, you have a tool to help, Auto Layout.
Auto Layout, in its essence, takes a large set of inputs
in the form of constraints, transforms them into equations,
uses linear algebra to give you a set of frames.
And that will give you the layout that you've specified.
Now, working with Auto Layout, you will find it's powerful
and flexible but can seem somewhat mysterious at times.
And that's why we're here today, to discover
and unravel the mysteries of Auto Layout.
We have a number of tips and techniques to tell you about,
and learning them will save you hours of development time
and save you from frustration.
Let's get started.
If you are new to Auto Layout, whether you're new or a veteran,
there is something in this talk for you.
You can refer to past WWDC sessions
if you need a refresher.
Let's take a look at the outline.
This is a two-part session.
We are covering the morning half today, right now,
and the afternoon one is in this very same room later on.
Let's get started with the first mystery,
mystery number one, maintainable layouts.
Now, when you are working with Auto Layout, you are going
to discover very soon you are going to work with constraints.
Picture developing a relationship between two views.
You can have a label on one side, a bundle on the other,
specify how far apart it's going to be, where it's going to go
into the superview,
and beautifully align them along their baseline.
Now, whether those specifications change for you
at runtime or design time, Auto Layout will do its thing.
Picture a more complex example.
This is the App Store
with GarageBand showing up as the app.
It has a number of controls inside.
It has a label at the top and some buttons, it's got an icon
to one side, a segmented control in between,
and then some preview images at the bottom.
We can use Auto Layout to lay this thing out
and adapt to different sizes.
And the constraints might look like this.
Now for the maintainability part.
Pretend that you were not the developer
who created this layout.
But your boss comes up to you and says,
I want a new control right underneath the essentials
and above the star rating.
Where do you start?
You are probably going to have to examine the controls
in the area, look at the constraints,
try to insert your button, break some of them,
and then reassemble it, hopefully it all works out.
There is a more maintainable way,
as you've guessed, that is Stack View.
New to iOS 9 and made even better than before on the Mac,
Stack View allows you to arrange your views linearly.
Stack View has parity across both platforms.
It is built on top of Auto Layout.
It manages the constraints of your subviews for you
so you don't have to, and it works well
when you add user constraints.
You can have a horizontal or vertical orientation or axis,
as well as other customizable properties,
such as the alignment.
Here you have a whole bunch of horizontal stack views,
and here are examples of top, center, bottom,
and baseline alignments.
There are other alignments as well.
As well as vertical stack views.
Here are examples of fill, leading, center, and trailing.
Now, one of the properties I want to draw your attention
to is really cool, distribution property,
and this one is also new to NSStackView
as well as it's on iOS 9.
This allows you to distribute along the axis,
and you can do some pretty complex distribution behaviors
without having to deal with any constraints.
Here we have examples of fill
so that we are filling the stack view.
Fill equally, fill proportionally, which is based
on the content size of the subviews, and equal spacing.
And there are other distribution options as well.
So we can build -- Thank you.
We can build this out of stack views, so I am going
to give you a demo inside of Interface Builder.
So I've got Xcode loaded.
With a view controller, and to set up my scene,
all I have done is dragged a whole bunch of controls
and images out from the Object Library and Media Library.
You can see they are all top-level labels,
buttons, and images.
Now we are going to go ahead and put these things into a layout.
So first I am going to select my button and my labels.
Then I am going to draw your attention to this new button
on the IB canvas, the Embed in Stack View button.
When you click on it, it's created my stack view
and affirmed my alignment and my axis.
Now we are going to tune the properties.
You can see in the Property Inspector up here
that we have the axis, alignment, distribution,
and spacing as some of the options,
and you'll notice there's also a plus here.
You can make this an iOS 9 size classable.
We are going to go ahead and adjust the alignment,
and for the people who have dealt with constraints before
in Auto Layout, you will note that all we need
to do now is switch it from trailing to leading.
Not touching any constraints.
Let's go ahead and stack a whole bunch of other views in here.
I am going to go ahead and click on my ratings,
stack them to horizontal -- create a horizontal stack view.
I am going to go ahead and drag that up
into my first stack view.
Now I am going to select the icon and the header,
click the Stack View button for that, and then finally,
the top three controls, and my layout is nearly there.
Now let's go ahead and tune some properties.
We have the top-level stack views selected.
I am going to go ahead and first adjust this alignment not
to center but to fill, so it's really filled
across the entire stack view.
And I am also going to spread it out so
that it's a little more -- it's got a little more spacing.
Let's say about 20 points, maybe 25.
Then we will also add some spacing into the stack view
with the labels and the buttons, so I am going to go ahead
and click on that and change its spacing,
and we will give it about five points.
We also want to add spacing between the icon and the header,
and I could go ahead and select
that stack view using the document outline.
Or I can hold down Control-Shift on my keyboard,
click over the icon, and get all the views underneath my
So we will click on the closest stack view to me,
the horizontal one, and increase that to about 25 points.
Let's go ahead and run this.
You can see it's got my layout, but we haven't positioned it
yet in the superview, and this is
where we are going to use constraints.
I am going to go ahead and take the stack view and put it
against the top and leading margins.
Then I am going to draw your attention to this other button
on the IB canvas that brings up the Pin menu and brings
up a pop-up for being able
to add your leading and top constraints.
And when I hit the Add button,
it's added the constraints for me.
Now, we also want to add to the bottom and the trailing,
but there's another trick
in Interface Builder that you can do.
You can control-drag between two views.
So I am going to control-drag from the stack view
to its superview and select Trailing Space
to Container Margin.
That's going to add my constraints.
For those already familiar with the menu, check it out,
there are a few new other features in there.
We are going to add another constraint to the bottom,
vertical spacing to bottom layout guide.
Now I am going to double-click on my constraints,
set their constants so they are flush against the edges,
and now when we run it, you can see it fits my superview.
Something isn't quite right yet.
Take a look at that segmented control.
It's a little too stretched.
What is going on there?
In fact, if we rotate this, it's a little too squished.
At the top-level stack view, it's looking at its subviews,
and all of them have the same priorities,
the same content-hugging priority
and content compression-resistance
We will talk more about that later on in the session,
but for what you need to know for now is that we need
to tell Stack View which one is going to win.
All I have to do is select the segmented control,
go into the sizing inspector, choose the priority section,
go ahead and adjust my hugging priority because I want
to have the segmented control hug tighter,
change it from 250 to 260.
You only need to go a little bit above its default.
Likewise, I wanted to resist compression and not get swished,
so I am going to also increase my vertical content compression
resistance from 750 to 760.
Now when we run it, it's looking much better.
Now remember - -- thank you.
Remember the original problem?
Our boss wanted us to add a new control.
So here's what you do.
You tell your boss, it's okay.
I've got it.
Then you go back to your desk, open up the storyboard,
search for the control --
in this case we will use a button --
drag it out from the object library,
and target which stack view you want to drop it in.
Then you go grab a coffee.
[ Laughter and Applause ]
I would also like to point out that Stack View handles Hidden
for its subviews really nicely.
You can set it programmatically or through Interface Builder.
It's like it collapses or is taken out of the view hierarchy
but is still owned by Stack View.
So if I mark Hidden, you can see everything adjusts accordingly.
We think you will find this useful.
That is the demo of Stack View.
I also wanted to point out that animation is really easy, too.
This is what it might look like.
Use a UIView Animate with Duration block and just go ahead
and modify the Hidden property of the subviews,
and we specially handle those.
Or you can put other animatable properties in there
for adjustment, including properties
on the stack view itself.
Try, for instance, adjusting the axis so it's going
between horizontal and vertical,
and you will see something pretty cool.
And of course, this is what it looks like on Cocoa.
Use NSAnimationContext, run animation group.
So what have we seen?
Let's take a look at the API first.
It's simple, familiar, straightforward.
You have your axis or orientation,
describing whether the stack view is horizontal or vertical.
We have seen the distribution, alignment,
and spacing properties.
And then you have methods for being able
to add new things to be stacked.
Add and arrange subviews.
There's also an insert and remove.
I want to draw your attention to the Arrange Subviews property.
This property returns you a subset of all of the views
that are owned by the stack view.
It returns you the views that are currently being stacked.
What that implies is that you can have views
that are not being stacked by Stack View, such as decorators
or overlays, and have a clean view hierarchy,
and we think you will find that useful.
All you need to do is call Add Subviews for those other cases.
What have we seen here?
Stack View is easy to build, easy to maintain,
we believe you are going to compose a lot of these things,
and because Stack View is about layout
and therefore it doesn't need to render its own background,
we've been able to do some optimizations.
So we have a special Transform Layer class that doesn't render
on its own that can make Stack View run fast
and even more performant than your regular views.
So it is lightweight.
We went from an example with many constraints
and a little bit of difficulty maintaining it down to just four
and a bunch of stack views, and this reads a lot nicer.
We feel that you can build most of your user interfaces
with stack views, so we recommend start with Stack View
and use constraints as needed.
And that is Stack View.
Now, for the cases where you need more than just Stack View,
you are going to have to --
I would like to invite up my friend Kasia to talk
about feeding the layout engine.
KASIA WAWER: Hi.
My name's Kasia.
I am on the iOS Keyboards Team, and I am here to talk to you
about proper care and feeding of your layout engine.
It's a finicky little critter, but it wants to do right by you.
If you treat it correctly, it will treat you correctly.
As you have seen over of the course of the week,
we have these new adaptive environments as well as all
of the different iPhone screen sizes we have.
It's critical to plan you layout property to work
across all these environments
and not spend too much time iterating
for every single screen.
So most people, when they are thinking about constraints,
think of them sort of like this.
You create some views, you create some constraints
in different ways, and you kind of throw them into a black hole.
And a layout pops out the other end.
Hopefully yours, possibly not.
So what I really want to do today is try and clear up some
of this mystery here and get it
so you are hitting your layout every time.
And we are going to start with changing constraints.
When I talk about changing constraints, I am mostly talking
about activating and deactivating constraints.
Those of you who have used Auto Layout before
and for a while may remember we originally had the concept
of adding and removing constraints to and from views.
Well, don't do that anymore.
Activate and deactivate is much better.
It's a class method on NSLayout constraint for both of them,
and there are some really big benefits
to using activate and deactivate.
Constraints find their own container.
They are more efficient.
And you don't need to own all the views
in your layout in order to use them.
So this all really boils down to just don't use add
and remove anymore.
Use activate and deactivate.
So there are a few other things to keep in mind
when you are thinking about changing your constraints.
Number one, never deactivate everything
If anybody has tried this,
you've probably seen some really odd things happen.
Not all the constraints in that array belong to you,
such as the ones the view uses to set itself up,
so weird things are going to happen.
Just please don't.
We will see why in a moment.
What you need to do instead is keep references to constraints
that you may need to change later, either in an array
of constraints or as individual constraints
so that you can manage things exactly the way you want to.
So let's take a look at changing constraints.
So I have here an iPad app that I've made with a bunch
of planets, and it's been set up for iPad
and it also has an iPhone mode,
so it should work well with multitasking.
Except that I am not actually removing any constraints,
so when I move from my nice vertical compact layout back
to my regular layout, I have lost all
of my nice curve that I had before.
So the first thing I might be tempted to do to try
to rectify this is to remove all
of the constraints in the superview.
And when I do that, I am also going to need
to reactivate any shared constraints.
But you will see all sorts of exciting things happen here
if you try to take this approach.
So here's my regular layout again.
And here it is still nice.
Hmm. That's not good.
And if I move back to the regular layout, well,
I didn't actually want to make the planets quite that giant,
so this is not really what I want to do.
So how do we do this properly?
I am going to take a moment to grab this code so you don't have
to watch me type it all out.
So in your trait collection did change, what you want
to do is check and see with each environment whether the other
set of constraints that you might need to change are active.
Here I have two arrays with eight constraints each
that differentiate between that vertical alignment
with the planets.
So if I check and make sure that that's active,
remove the ones -- or deactivate the ones I don't want anymore
and activate the new ones, it should look much better.
Regular. Still regular.
Compact. And regular again.
So that's where I actually want it to be.
Oh, thank you.
So a cool thing in Auto Layout is
that you can actually animate constraint changes as well.
Here I have a double-tap gesture to animate between this regular
and compact layout by dropping that activation and deactivation
into an animation block along with a call of layout
if needed to the superview.
So you'll see if I double-tap, I can move really nicely
between the set of views with just a couple lines of code.
And if you want to get fancy, you can keep references to all
of those individual constraints and use keyframe animations
to really kind of spice things up in your app.
So that's activating
and deactivating constraints properly.
So what do we know about changing constraints?
Well, number one,
never deactivate self.view.constraints.
We know that very well now.
Keep references to constraints are going
to change in the future.
It will make everything work better,
and you can do cool things like animation.
And you can also animate changing constraints
by just dropping it into a View Animation block,
which is pretty cool.
So we are still at the kind of basic part
of building our layout, where we still have our views
and constraints and are putting them into the layout engine.
But if we give the layout engine more information,
we can get a lot better results that work properly
in all these different adaptive environments.
So we have kind of positioning for all of our constraints,
and now I want to talk about size.
So mystery number three, view sizing.
There are a couple different ways to size your views,
and you no longer have to say,
I want a view that's 200 points wide, 300 points tall.
Instead, you can use different ways
to create your constraints adaptively to, you know,
work in all of our various environments we have
for you now, and we start with intrinsic content size on that.
Many views have this, such as labels and image views,
and it's basically the size that the view would be
if it was just right around its content.
And the engine looks at this and tries to solve your layout
at this size, and it will actually create the internal
size constraints for you.
But it can't guarantee the layout size because of stuff
like adaptivity, it needs to be able to stretch
and shrink views a little bit.
So around things like this, the user won't see it,
but you might have a few extra points
of padding here and there.
So you can use this in order to lay out your views in a way
that means you don't have to specify
that this label is this wide.
It will simply be as wide as its content.
But if you need to define a particular view size,
start with constraints.
It's very easy to do things like,
this view should be half the width of my superview.
This one should be three-quarters
of the height of my superview.
This one should be equal to the view next to it.
You can, however, override that intrinsic content size
if you absolutely need to.
There are only a couple reasons you might need to do that.
One is if you can't get the size information
from the constraints.
And another might be if you are using custom drawing
in your view.
But a lot of times you can still just set up the constraints
for that view, and you won't have to do anything
with overriding intrinsic content size.
If you do override intrinsic content size,
you are responsible for invalidating it
in case the slide class changes or the text changes
that you've got dynamic text, localization,
or anything like that that may cause your view to need
to recalculate its internal size.
So let's look at setting up a view with constraints
without using any particular point sizes,
all in relationships.
Here we have a standard image view.
So what I want this to take up most of my view,
so I want the width to be equal to three-quarters
of the view that it's in.
That means that every environment it's in,
the width will be three-quarters of that view.
So I set that up first.
And then I can take that proportion that I now have
from calculating from the superviews with and multiply it
by one and a half to get the height.
And this will give me a consistent layout
across all devices and all modes in multitasking.
So view sizing is important, and the more you rely
on proportions, the more likely you are to have a good layout
that will really, you know, be easy for you to put
across all these different screens we are giving you.
And one of the things that a lot of people when they think
about sizing views think about is self-sizing views,
and most particularly self-sizing table view cells.
And these are cells that get their height from their content
so that you don't have to have one size of cell all up
and down your table view.
You can have them in different sizes depending
on what's inside of them.
And you don't actually have
to calculate every row height yourself.
The constraints can help you with that.
So self-sizing needs to get its size from your constraints.
Again, this doesn't mean points.
This means proportions and relying on things
like intrinsic content size to help you sort of do that.
Width is defined with table view cells already, so you just need
to worry about height.
And you can take advantage of proportions to do this.
Here we have a table view cell.
The label should be twice as wide as the image view,
and they have a little bit of padding between them.
So when I have a label that's taller because it has more text,
the table view cell grows in order to accommodate that.
So let's look at a quick demo of how that's done.
Okay. So here I have my table view cell that I have set
up the horizontal constraints for already.
If I were to just build and run it the way it is,
it would not be exactly what I was hoping for.
So everything is kind of squished.
My estimated table view height is 60,
so it's drawing it there by default.
So what I want to do now is tell the table view cell
that if the label grows, it grows with it.
And I do that by putting their top and bottom anchors together.
So then the label is going to go ahead and push against the size
of the table view cell and make it taller.
So top space and bottom space, to container margin.
Let's see what we get here.
This is better.
But it's still not quite what I wanted.
Because we have cells like this one
where the image is now cut off
because the label isn't tall enough.
So to fix this, we can take advantage of the fact
that views can stretch beyond their intrinsic content size
and tell the label that it should be
at least as tall as the image.
And so the label will get some extra padding around it
that will allow it to -- to start at the height of the image
and stretch beyond that when it's tall enough.
So you don't see that extra spacing,
and the text stays nice and centered.
But the label is still what's defining the height
of the table view cell.
And now that looks much better.
All of my cells are properly sized,
and I can see everything I wanted to see.
And that's really all that's involved
in creating self-sizing table view cells.
Just making sure that everything is fully defined.
So view sizing.
What have we got?
Certain views have an intrinsic content size.
You can use that when you are defining relationships
to other views.
Constraints should define your size when possible.
When not, you can override intrinsic content size,
but make sure you invalidate intrinsic content size
when you do so.
For self-sizing views, you just need
to define the size fully in your constraints.
Where are we building the layout?
We have our original information.
We are going to add some sizing constraints.
From the views we just put together,
their intrinsic content sizes.
How do we help layout engine know what we want?
We give it some priorities.
This is mystery number 5.
If you have been doing Auto Layout for a while,
you may have landed in a situation
where views aren't landing where you expect them
to in regard to their superview.
Maybe on each build and run it's a little bit different,
or if you rotate or resize it gets a little bit different.
So that's called ambiguity.
And it can happen for a couple different reasons.
One is because you don't have enough constraints
in the direction you are looking for.
So for instance, if I had Saturn here kind of where I wanted it
in the middle, in this dotted line, but when I actually ran
that app it ended up way off to the left or right,
that might mean that I don't have enough horizontal
constraints to tell the engine where to put Saturn.
Vertically it seems fine, so that's good.
And the other thing that can cause this is equal
Equal required priorities often calls unsatisfiable constraints
if the layout engine can't solve your view that way.
Equal nonrequired priorities means the engine has
to make a choice for you.
And it tries really hard to make a good choice,
but it doesn't really know what you want.
So you just need to give it a little bit more information
to get there.
So how do priorities work?
They go from 1 to 1,000, and we have a couple of constants
to help you balance your priorities.
One thousand is layout priority required.
Default high is 750, and default low is 250.
And they look like this in a visual format language,
you simply put an @ symbol before the number you wish
In Interface Builder, you can stick it right
into a text field here.
And if you are using explicit constraints, it's a property.
And that's where you can actually use these constants
or numbers or a combination of the two.
The highest priority, when they are competing, wins.
And we'll look at this in the context
of content priorities in a moment.
But an important note.
The system has some priorities that it uses to lay
out its views internally.
On iOS, we have system layout size fitting size at 50,
and there are several window priorities around 500 --
490, 500, and 510 -- that OS X uses.
If you look at the NSLayoutConstraint header,
you will see what those numbers are.
If you set those equal to each other,
you may end up in these ambiguous situations
that you're about to see.
You want to use something that's a little higher or lower
than the priorities the system is using.
These are how a view handles its content.
By default, they are set as Not Required,
and you should not set them as Required.
Content needs to be able to move a little bit.
We have dynamic text.
We have localization.
We might be able to have users choosing different images,
stuff like that.
It needs to have a little bit of wiggle room.
You can't say it always has to be this size.
You will end up with unsatisfiable
But equal priorities that are not resolved can cause
ambiguity, as I said earlier.
Let's look at an example of this using content-hugging
priorities, which is one of the two types
of content priorities that we have.
Here we have a text field and button,
and the text field is all squished off to the side,
and the button is all spread out.
That's because they both have a content-hugging priority
at their default, which is 250.
The engine needed to make a choice,
and it wasn't sure whether the answer was this or this.
So you can actually tell it what answer it should choose every
time instead of getting one
or the other depending on your environment.
So if you bring the button's content-hugging priority
down to 249, you will get the first layout.
And this is because the engine looks at your constraints
and your priorities and says, oh,
the text view hugging priority is fairly important,
but the button hugging priority is not at all important,
so I can go ahead and stretch that away from its content
to fill up this horizontal part of your view here.
Meanwhile, if you take the button
and you put its content-hugging priority above that
of the text field, you will get the other solution
because the engine says, hey,
now I want to hug this button text really closely,
and that means that I can stretch the text field
in order to solve your layout.
And that's really all that's required
to adjust an ambiguous situation like that.
The other type of content priority is
And this is how much a view resists its content
So if you have -- squished is a technical term, by the way.
Feel free to use it whenever to impress people.
Compression resistance priorities for image views
and labels in the horizontal direction default at 750,
and that's a very high priority because generally you want
to see all of your content.
But what if you localize this app?
And you had these two things that were competing,
and you had a language that used a much longer word for
"red," such as Polish.
It could get clipped.
This is one of the choices that the engine has to make.
It can either shrink the image view or clip your label.
It doesn't really know what you want it to do,
so it makes that choice.
If you wanted the label to always show all of its content
and it was okay to shrink that image a little bit, again,
all you have to do is set the labels content compression
resistance priority slightly higher than that
of the image view, and now you can see the whole view.
So as you localize, that's the adjustment that's made in order
to make sure that all of your text is visible
to your audience.
So those are priorities.
They can help you solve unsatisfiability,
which is that thing that causes that horrible log that you see
when you build and run and everything is broken.
So they are really helpful, but you want to look
out for competing priorities.
If they are competing, you can get ambiguity, as you just saw.
Results are more consistent across screens
and windows when you do this.
If you use content priorities well,
you can get to the right layout.
Sometimes all that's needed is adjusting hugging
or compression resistance a little bit.
Now in building our layout, we have added some priorities
for your constraints and your content.
So what else do we need in order to finish solving this layout?
Again, if you have been using Auto Layout, you are familiar
with aligning your views.
They need to have some sort of horizontal alignment,
so they know how to relate to each other, and some sort
of vertical alignment.
I am going to talk specifically here about aligning text.
So first of all, with text views, we have the concept
of a baseline, and this is the line right
under the bottom of the text.
Text views have a first baseline
and a last baseline alignment thing, where you can --
the first baseline runs right under the first line of text,
and the last baseline runs right under the last line of text.
A single-line text view has these two equal to each other.
So it aligns text better than top or bottom
in many circumstances and helps with stuff
like dynamic text sizing.
It gives you better control over changing views as well
if something needs to grow.
For instance, if you have a label next to a button
and they are aligned by the bottom, the button's frame
in this instance is a little large
because it's filling in some extra space.
So if I add a couple of lines of text to it, the button can sort
of end up in a nebulous area.
And I might want to center align that, or it might be better
to have it look more something like messages
and have it sit right at the bottom next
to that last line of text.
So if I just align them by last baseline, no matter what
that text view does, the button will stay aligned
with that last baseline.
And of course, you can also do it for the first baseline
if that's the sort of view you desire.
So as you have a growing view, it's staying aligned
with the views around it.
The other important part of text alignment is leading
This is actually important for all types of views,
but its big use is for localization.
If you are in a left-to-right language
when you are writing your app and you use left
and right constraints for your layout and it gets localized
to a language that uses right-to-left, you're going
to get some odd results.
It will look something like this.
Everything sort of flips in place,
but it no longer reads properly.
I was reading from the image view over through the text,
and now I am reading the text from the other direction
and it's going over to the image view.
That's not really what I wanted.
If you use the exact same constraints with leading
and trailing alignments instead, leading for left and trailing
for right, you would end up with the correct layout,
where everything actually reads exactly the way you originally
designed it when you switch to a language that goes
in a different orientation than the one you were starting with.
So use leading and trailing pretty much always.
There might be some circumstances
where you still need to use left and right.
I am not familiar with any right now.
I am sure that you guys have a few.
But if you do use left and right at all,
be careful when you are mixing and matching that with leading
and trailing because, again, when that environment changes,
you might end up with unsatisfiable constraints.
Okay. Final piece
of our alignment puzzle is alignment rects.
Alignment rects are important
because it's what the engine actually calculates.
The engine takes all of your constraints,
calculates the alignment rects, and uses them
to actually lay out your views.
So what are alignment rects?
They are usually the frame of the view, but not always.
Instead of just being the frame around the view,
it includes the critical content of the view,
which is what you really want to align.
Here we have a checkbox, for instance,
where if you were doing a center x alignment
with some other view, you would probably want to align it
by the center of the circle and not by the center
of the checkbox, the whole check,
which would be a little bit too high.
Same thing with a button that has a shadow.
It kind of gets rid of those little extra bits and focuses
on the critical part of the content.
It doesn't change when the view transforms, either.
So when you lay out your view and want to emphasize
or deemphasize something, it won't mess up the rest
of your layout to throw a transform in there.
If you do need to change these,
which you should very rarely need to do, we have an override
for alignment rect insets you can use.
And that basically means you can hand the engine, say, oh,
whatever alignment rect you are calculating,
inset it by this much and use that instead.
You will very rarely if ever need to do that in your layout,
but it is there if you need it.
To find out what the engine has actually calculated for you,
you can draw it on your view using the view debugging option
in the Debug menu of Xcode
and just selecting Show Alignment Rectangles.
This will draw yellow alignment rectangles on your view.
You can also get it from the debugger using alignment rect
for frame on specific views.
We are going to talk about that more in Part 2 when we talk
about debugging layouts, so definitely tune in there
if you want to learn more about how all this works.
So for alignment, we've learned
that text is a little bit different than everything else.
You want to make sure that you are ready for both dynamic text
and localization when you are preparing your app,
and Auto Layout can really help you with that.
You also have this possibility
of overriding alignment rect insets
if you have very interesting, specific views that need to sit
in a very specific frame.
So where are we in our layout?
Okay. We have now alignment, and if we needed to,
we overrode a couple of alignment rect insets.
Now we are ready to let the engine do its work.
So let's throw everything in there.
The layout engine will think about it,
calculate your alignment rects, and then that will be used
to actually build the layout.
Now you have a very happy layout that's exactly what you wanted
for every screen size.
Trust me, this is your layout that you wanted.
So let's see.
Let's summarize what you've learned today.
Stack views are a great way to build a maintainable layout
that will work well across all of our devices and sizes.
And you can use -- if you use activate and deactivate properly
for your constraints, you can get really dynamic,
interesting layouts that require less work than having to design
for every single screen.
When you determine specific sizes, use constraints.
Override intrinsic content size only when absolutely necessary.
Use priorities to get those last little adjustments together.
Finally, alignment goes beyond top, bottom, and center,
especially when you are looking at text, keep localization
and dynamic text in mind.
For more information about all of this,
we've got some documentation up.
You can download that planets sample code if you want to play
around with animation, and of course,
you can go to the forums or, in a pinch, contact our Evangelist.
Tune in this afternoon for Mysteries of Auto Layout Part 2,
where you will learn more about the layout cycle in depth
and more information
about debugging a layout that's not doing what you want it
We have some other related sessions here.
Have a great day.
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.