The Ultimate Guide to iOS AutoLayout (V): AutoLayout Animations - Digital Leaves
page-template-default,page,page-id-2121,qode-social-login-1.0,qode-restaurant-1.0,ajax_fade,page_not_loaded,,select-theme-ver-4.1,wpb-js-composer js-comp-ver-5.2,vc_responsive

The Ultimate Guide to iOS AutoLayout: Demistifying NSLayoutConstraint. Size Classes. AutoLayout Guide. Autolayout Animations. Animations With AutoLayout.
Welcome back! This is the final episode of “The Ultimate Guide to iOS AutoLayout”, “AutoLayout animations. In the previous episodes, you mastered AutoLayout, from defining constraints and rules in IB, responsiveness and Size Classes, to programmatically add constraints via NSLayoutConstraint. Finally, in this last episode, we are going to talk about how to create beautiful animations using AutoLayout constraints.

Why AutoLayout Animations?

Before AutoLayout, we had springs and struts. To organize the views on the screen, you would specify their relative position and how they were allowed to grow. In this scenario, we animated views by directly modifying some of their properties, like the frame or the alpha. We used the class method animateWithDuration:animations: like in this example:

This concrete example moves the view 50 pixels in both the X and Y axis. Besides, it doubles the size of the view. As you may see, this way of animating views was as simple as defining the “final situation” of those views inside an animate block. After the block finishes animating the views, they are left in a “stable” situation in its new configuration.

However, with the introduction of AutoLayout, there’s a problem with this approach, specially regarding the position and size of the views. The figure below describes this issue perfectly:

AutoLayout animations. Status of AutoLayout constraints after animation.

If you just change the parameters of the view (width, height, position…), the AutoLayout constraints haven’t changed. This means that the view is in an “unstable” situation. Its position and size are “incorrect” according to its AutoLayout constraints. As a result, any layout operation will return the view back to its correct configuration. This happens, for instance, if we present and dismiss a view controller. If our view is inside a UITableViewCell, refreshing the cell will also rollback the animation.

Thus, if we are using AutoLayout in our project (and you really should), we need to change our approach. Let’s see how to properly do AutoLayout animations in our projects.

How to do AutoLayout Animations

In order to correctly perform animations in an AutoLayout-enabled project, we need to modify the AutoLayout constraints of our views, and then animate those changes. How? Thanks to the method layoutIfNeeded().

First, we need to create outlets for our constraints.

Next, before entering the animation, we set the new values for the AutoLayout constraints.

Then, we call UIView.animateWithDuration:animations: or any of its variants.

Finally, inside the animations block, we just call layoutIfNeeded() in the superview of the view we want to animate.

Why do we call layoutIfNeeded() in the superview and not the view we want to animate? Because of how the method has been built:

Use this method to force the layout of subviews before drawing. Using the view that receives the message as the root view, this method lays out the view subtree starting at the root.

The second part of the definition seems to contradict the first one, but in practice, it’s clear that layoutIfNeeded() acts on the subviews of the receiving view. Thus, call layoutIfNeeded() on the superview.

Specially relevant is the fact that this only applies to position and size. The rest of properties of a view that can animated need the animations to be applied to that subview, and inside the animation block. The alpha value is an example, in the code snippet above. We animate the view’s position via AutoLayout, but the opacity is animated inside the block, directly on the view.

Examples of AutoLayout animations

Let’s see some examples in action. As always, you can download a project with the source code containing all these examples from my Github repository.

Moving a view

First, let’s do a basic animation. We will be moving a view from the left side of the screen to the right. In order to do that, we center the view vertically, and also add a leading constraint. This constraint will pin the view to the left edge. We make sure to disable the “Constrain to margins” checkbox to use absolute offsets, in this case, 16px. Then, we define an outlet for this leading constraint like we learned to do in the previous episode of this guide. Finally, we will calculate the value we should place in the constant for this constraint if we want our view to move to the other side of the screen. To calculate it, we get the width of the screen via the UIScreen.main.bounds.width property. We must subtract another 16px (for margin) and another 64px (the width of the square view):

We also add an “animating” property to prevent the button from launching the animation while it’s currently animating. Next, we define a method to switch the constraint’s constant depending on the current position of the view:

Finally, we call UIView’s animateWithDuration:animations: and invoke layoutIfNeeded() inside the animation block.

The result, as you see in the video, is a nice animation.

Resizing a view

Resizing a view is quite similar. In our example, we will grow and shrink a centered subview:

In this case, we will need a constraint for the width and another for the height of the view. We will also define the initial size of the view in a constant:

Then, using a similar schema from the previous example, we will just switch from this initial size to double that quantity in switchConstraintForBoxView:

Furthermore, you could remove the height constraint, set a 1:1 aspect ratio, and just animate the width (or the height).

Combining position and size animations

Let’s combine a position and size animation in an endless loop. We will start with our square view at the top left corner, and grow it to twice its size while it transitions to the bottom right corner of the screen. The video shows the desired animation:

We will need constraints for both the position (top and left distance to edges) and size:

Then we’ll define initial values for all of them:

And we will change them from the initial to the final position. We will use a loop option (autoreverse and repeat options) for a funny result:

As a result of the options applied to animate:withDuration:animations, the animation repeats itself in an endless look.

Spring AutoLayout animations

Finally, we will apply spring parameters to our AutoLayout animations. If you don’t know what spring animations are, have a look at the video and compare it with the first movement animation I showed.

Notice how the view accelerates and bounces in a more natural way? Usually, objects in real life don’t transition from point A to point B with an homogeneous velocity. Real interactions are subject to acceleration, gravity and other impulses. Our initial animation completely lacks any of those qualities. The result is a poor animation that’s not perceived as “real”. “Spring” animations, therefore, were introduced to model more real object interactions. These animations have two main parameters in iOS: dumping ratio and velocity.

The first is, in my mind, the “resistance” that the view offers to bouncing. A dumping ration of 1 will produce a bounce-less movement, whereas a low dumping ratio will cause the view to “jump” outside of the animation range and go back. The official definition by Apple is:

The damping ratio for the spring animation as it approaches its quiescent state. To smoothly decelerate the animation without oscillation, use a value of 1. Employ a damping ratio closer to zero to increase oscillation.

The Spring velocity defines the initial impulse of the view. Bigger velocities produce a more “accelerated” start for the animation. This is the official definition by Apple:

The initial spring velocity. For smooth start to the animation, match this value to the view’s velocity as it was prior to attachment. A value of 1 corresponds to the total animation distance traversed in one second.

Therefore, in our example, we’ll use the same constraint modifications that in the first one. The difference will be the call to UIView’s animate:

See the difference? Using spring effects in our AutoLayout animations can really make a difference in our UI/UX.

Where to go from here

With this episode, we conclude “The Ultimate Guide to iOS AutoLayout”. First, you learned the basics of AutoLayout and how to avoid conflicts and ambiguity. Next, you mastered responsive interfaces and size classes. Then, you acquired AutoLayout-ninja skills by learning to use NSLayoutConstraint and define constraints programmatically. Finally, in this “AutoLayout animations” episode, I have taught you how to properly animate your views in an AutoLayout scenario.

If you haven’t already, I recommend you to read my post: “Towards responsive iOS Design: Beyond AutoLayout and Size Classes“. In this article, I explain how to approach user interfaces design in iOS following the principles of responsive design.

I hope you have enjoyed it and found it useful. If you have specific questions, don’t hesitate to contact me.

Before you continue...

Hi there! I created the Digital Tips List, the newsletter for Swift and iOS developers, to share my knowledge with you.

It features exclusive weekly tutorials on Swift and iOS development, Swift code snippets and the Digital Tip of the week.

Besides, If you join the list you'll receive the eBook: "Your First iOS App", that will teach you how to build your first iOS App in less than an hour with no prior Swift or iOS knowledge.

I hate spam, and I promise I'll keep your email address safe.