[MUSIC PLAYING]
So constraints.
They're a great way for you, as a developer,
to deal with the ever expanding number of screen sizes, device
rotations, and new form factors like slide
over in the iOS world.
But one unfortunate casualty in this brave new world
of alignment has been the way we animate views.
See, it used to be, we could go around setting a UI views
position or frame with a fun little UI view
animate with duration method and watch our views
scoot around the screen.
That was fun.
But that's harder to do in a world full of constraints.
Constraints don't necessarily play nicely
with a view whose frame you're setting explicitly,
as you can see here.
Well, that leads us to this episodes quick tip,
sent in by Jacob Cho, a fan of Route 85
and a software engineer at Ensemble, a mobile app
developer located in beautiful Vancouver, British Columbia.
Jacob notes that many iOS developers forget
that, in addition to the old way of animating a view's position,
you can also animate constraints in iOS.
Let's look at how you might do that.
Here's my storyboard and, as you can see here,
I've got everything set up nicely using constraints.
Now, to move my UI image view on and offscreen,
I'm going to want to change this constraint here,
the one that sets my images leading edge to the leading
edge of my super view.
Right now, it's set to minus 180, so it's off screen.
So first I'm going to control drag from this constraint
into my view controller, to make it an IB outlet of type NS
layout constraint.
This allows me to access it in my code.
Now I can adjust it with a standard
UIView.animateWithDuration call.
In this case, I'll change the constant of the constraint
from minus 180 to 0, so that it appears on screen.
And now we can give it a try.
Huh, that's weird.
The constant definitely changed but what
happened to my animation?
Well, it turns out, to get this constant to animate nicely,
I need to call layoutIfNeeded on my view controller's view,
within this animation block.
We'll give it one more and, oh, that's much better.
I now have a constraint that I can change within an animation
block and everything animates smoothly to its final position,
except in cases where I want to adjust
something besides my constraint's constant.
Let's take a look at another example.
Here, I want to adjust this center square
to expand or shrink to be either twice or half
the width of its neighbors.
Now I could do that, in theory, by adjusting the multiplier
on the center views with constraint.
But it turns out that changing that multiplier in code
doesn't work.
See, constraint multipliers are a get only property,
and Xcode will give me an error.
So how do I change it?
Well, the answer is I don't.
Instead, I create two completely different constraints
and enable or disable either one as necessary.
As long as I'm still calling layoutIfNeeded in my animation
block, this kind of change will still animate.
Now, there are two ways I can accomplish
this constraint swapping.
One way is to create both constraints
in Interface Builder, like so.
Now Xcode will complain that these are incompatible,
and it's right.
So first step, we'll uninstall one of them
by checking this box here.
Next, we'll control drag both of these constraints
into our code to make them IB outlets.
And then I can enable or disable these, as necessary,
in my animation block, like this.
Once again, you'll notice I make sure we're
calling layoutIfNeeded in our animation block
and we end up with a nice, smooth looking animation.
Look at that.
The other way to accomplish this would
be to create a completely new constraint in code.
This is useful when I don't know in advance
what I'm going to want this multiplier to be
and I need to create it dynamically.
So let's see that in action.
This time in my animation block, I'll first
remove the old constraint.
Next up, I can create a new multiplier.
Let's make it slightly random, just for fun.
Oh, hey, that is fun.
OK, next I'll create a brand new constraint
with this new multiplier and assign it to my center view
with property.
And then it can add it back in again to my view.
Finally, I call layoutIfNeeded on this super view
in the animation block and I once again
have some nicely animating views that use this new constraint
that I've created.
And because this is all done using constraints,
you'll notice this works as intended on an iPhone,
an iPhone in landscape mode, or even, say,
a slide overview on an iPad.
And once you understand that this trick simply
involves removing an old constraint
and adding a new one, you might discover
a whole new world of animation is available to you,
simply by turning on and off various constraints.
For example, on this screen, I can change all my views
to be either left aligned or right aligned,
simply by adding and removing two different groups
of constraints and then calling our now
familiar layoutIfNeeded method.
Pretty neat, huh?
Oh by the way, one fun little quirk about all this.
If you add your new constraints before you remove the old ones,
iOS will complain about all the incompatible constraints
it has to deal with in those like few milliseconds.
So always make sure you remove the old ones first
before adding the new ones.
So thanks to Jacob for the quick tip.
Jacob, you're going to get a very stylish Google t-shirt
in the mail, but hang on.
We're not done yet.
You see, now that you know all about constraint animation,
I have a couple more quick tips from one of Google's engineers
about more efficient ways to implement it.
So follow me onto the next video,
because we're not done learning just yet.
Click here, click here.
And, otherwise, I'll see you on Route 85.
Bye.
[MUSIC PLAYING]