iOS Animation Tutorial: Getting Started

Marin Todorov

Animations-feature-1-getstartedAnimation is a critical part of your iOS user interfaces. Animation draws the user’s attention toward things that change, and adds a ton of fun and polish to your apps UI.

Even more importantly, in an era of “flat design”, animation is one of the key ways to make your app stand apart from others.

In this tutorial, you’ll learn how to use UIView animation to do the following:

  • Set the stage for a cool animation.
  • Create move and fade animations.
  • Adjust the animation easing.
  • Reverse and repeat animations.

There’s a fair bit of material to get through, but I promise it will be a lot of fun. Are you up for the challenge?

image001

All right! Time to get started.

Your First Animation

Download and open the starter project for this tutorial. Build and run your project in Xcode; you’ll see the login screen of a fictional airline app like so:

image003

The app doesn’t do much right now; it just shows a login form with a title, two text fields, and a big friendly button at the bottom.

There’s also a nice background picture and four clouds. The clouds are already connected to outlet variables in the code named cloud1 through cloud4.

Open ViewController.swift and have a look inside. At the top of the file you’ll see all the connected outlets and class variables. Further down, there’s a bit of code in viewDidLoad() which initializes some of the UI. The project is ready for you to jump in and shake things up a bit!

Enough with the introductions — you’re undoubtedly ready to try out some code!

Your first task is to animate the form elements onto the screen when the user opens the application. Since the form is now visible when the app starts, you’ll have to move it off of the screen just before your view controller makes an appearance.

Add the following code to viewWillAppear():

heading.center.x  -= view.bounds.width
username.center.x -= view.bounds.width
password.center.x -= view.bounds.width

This places each of the form elements outside the visible bounds of the screen, like so:

image005

Since the code above executes before the view controller appears, it will look like those text fields were never there in the first place.

Build and run your project to make sure your fields truly appear offscreen just as you had planned:

image007

Perfect — now you can animate those form elements back to their original locations via a delightful animation.

Add the following code to the end of viewDidAppear():

UIView.animate(withDuration: 0.5) {
  self.heading.center.x += self.view.bounds.width
}

To animate the title into view you call the UIView class method animate(withDuration:animations:). The animation starts immediately and animates over half a second; you set the duration via the first method parameter in the code.

It’s as easy as that; all the changes you make to the view in the animations closure will be animated by UIKit.

Build and run your project; you should see the title slide neatly into place like so:

image009

That sets the stage for you to animate in the rest of the form elements.

Since animate(withDuration:animations:) is a class method, you aren’t limited to animating just one specific view; in fact you can animate as many views as you want in your animations closure.

Add the following line to the animations closure:

self.username.center.x += self.view.bounds.width

Build and run your project again; watch as the username field slides into place:

image011

Seeing both views animate together is quite cool, but you probably noticed that animating the two views over the same distance and with the same duration looks a bit stiff. Only kill-bots move with such absolute synchronization! :]

Wouldn’t it be cool if each of the elements moved independently of the others, possibly with a little bit of delay in between the animations?

First remove the line you just added that animates username:

self.username.center.x += self.view.bounds.width

Then add the following code to the bottom of viewDidAppear():

UIView.animate(withDuration: 0.5, delay: 0.3, options: [],
  animations: {
    self.username.center.x += self.view.bounds.width
  }, 
  completion: nil
)

The class method you use this time looks familiar, but it has a few more parameters to let you customize your animation:

  • withDuration: The duration of the animation.
  • delay: The amount of seconds UIKit will wait before it starts the animation.
  • options: Lets you customize a number of aspects about your animation. You’ll learn more about this parameter later on, but for now you can pass an empty array [] to mean “no special options”.
  • animations: The closure expression to provide your animations.
  • completion: A code closure to execute when the animation completes. This parameter often comes in handy when you want to perform some final cleanup tasks or chain animations one after the other.

In the code you added above you set delay to 0.3 to make the animation start just a hair later than the title animation.

Build and run your project; how does the combined animation look now?

image013

Ah — that looks much better. Now all you need to do is animate in the password field.

Add the following code to the bottom of viewDidAppear():

UIView.animate(withDuration: 0.5, delay: 0.4, options: [],
  animations: {
    self.password.center.x += self.view.bounds.width
  }, 
  completion: nil
)

Here you’ve mostly mimicked the animation of the username field, just with a slightly longer delay.

Build and run your project again to see the complete animation sequence:

image015

That’s all you need to do to animate views across the screen with a UIKit animation!

That’s just the start of it — you’ll be learning a few more awesome animation techniques in the remainder of this tutorial!

Animatable Properties

Now that you’ve seen how easy animations can be, you’re probably keen to learn how else you can animate your views.

This section will give you an overview of the animatable properties of a UIView, and then guide you through exploring these animations in your project.

Not all view properties can be animated, but all view animations, from the simplest to the most complex, can be built by animating the subset of properties on a view that do lend themselves to animation, as outlined in the section below.

Position and Size

image017

You can animate a view’s position and frame in order to make it grow, shrink, or move around as you did in the previous section. Here are the properties you can use to modify a view’s position and size:

  • bounds: Animate this property to reposition the view’s content within the view’s frame.
  • frame: Animate this property to move and/or scale the view.
  • center: Animate this property when you want to move the view to a new location on screen.

Don’t forget that in Swift, several UIKit properties such as size and center are mutable . This means you can move a view vertically by changing center.y or you can shrink a view by decreasing frame.size.width.

Appearance

image019

You can change the appearance of the view’s content by either tinting its background or making the view fully or semi-transparent.

  • backgroundColor: Change this property of a view to have UIKit gradually change the background color over time.
  • alpha: Change this property to create fade-in and fade-out effects.

Transformation

image021

Transforms modify views in much the same way as above, since you can also adjust size and position.

  • transform: Modify this property within an animation block to animate the rotation, scale, and/or position of a view.

These are affine transformations under the hood, which are much more powerful and allow you to describe the scale factor or rotation angle rather than needing to provide a specific bounds or center point.

These look like pretty basic building blocks, but you’ll be surprised at the complex animation effects you’re about to encounter!

Animation Options

Looking back to your animation code, you were always passing [] in to the options parameter.

options lets you customize how UIKit creates your animation. You’ve only adjusted the duration and delay of your animations, but you can have a lot more control over your animation parameters than just that.

Below is a list of options declared in the UIViewAnimationOptions set type that you can combine in different ways for use in your animations.

Repeating

You’ll first take a look at the following two animation options:

  • .repeat: Include this option to makes your animation loop forever.
  • .autoreverse: Include this option only in conjunction with .repeat; this option repeatedly plays your animation forward, then in reverse.

Modify the code that animates the password field viewDidAppear() to use the .repeat option as follows:

UIView.animate(withDuration: 0.5, delay: 0.4, 
  options: .repeat,
  animations: {
    self.password.center.x += self.view.bounds.width
  }, 
  completion: nil
)

Build and run your project to see the effect of your change:

image023

The form title and username field fly in and settle down in the center of the screen, but the password field keeps animating forever from its position offscreen.

Modify the same code you changed above to use both .repeat and .autoreverse in the options parameter as follows:

UIView.animate(withDuration: 0.5, delay: 0.4, 
  options: [.repeat, .autoreverse],
  animations: {
    self.password.center.x += self.view.bounds.width
  }, 
  completion: nil
)

Note how if you want to enable more than one option you need to use the set syntax and list all options separated with a comma and enclose the list in square brackets.

Note: If you only need a single option, Swift allows you to omit the square brackets as a convenience. However, you can still include them in case you add more options in the future. That means [] for no options, [.repeat] for a single option, and [.repeat, .autorepeat] for multiple options.

Build and run your project again; this time the password field just can’t make up its mind about staying on the screen!

Animation Easing

In real life things don’t just suddenly start or stop moving. Physical objects like cars or trains slowly accelerate until they reach their target speed, and unless they hit a brick wall, they gradually slow down until they come to a complete stop at their final destination.

The image below illustrates this concept in detail:

image025

To make your animations look more realistic, you can apply the same effect of building momentum at the beginning and slowing down before the end, known in general terms as ease-in and ease-out.

You can choose from four different easing options:

  • .curveLinear: This option applies no acceleration or deceleration to the animation.
  • .curveEaseIn: This option applies acceleration to the start of your animation.
  • .curveEaseOut: This option applies deceleration to the end of your animation.
  • .curveEaseInOut: This option applies acceleration to the start of your animation and applies deceleration to the end of your animation.

To better understand how these options add visual impact to your animation, you’ll try a few of the options in your project.

Modify the animation code for your password field once again with a new option as follows:

UIView.animate(withDuration: 0.5, delay: 0.4, 
  options: [.repeat, .autoreverse, .curveEaseOut],
  animations: {
    self.password.center.x += self.view.bounds.width
  }, 
  completion: nil
)

Build and run your project; notice how smoothly the field decelerates until it reaches its rightmost position, before returning to the left side of the screen:

image027

This looks much more natural since that’s how you expect things to move in the real world.

Now try the opposite. Ease-in the animation when the field is still outside of the screen by modifying the same code as above to change the .curveEaseOut option to .curveEaseIn as follows:

UIView.animate(withDuration: 0.5, delay: 0.4, 
  options: [.repeat, .autoreverse, .curveEaseIn], 
  animations: {
    self.password.center.x += self.view.bounds.width
  }, 
  completion: nil
)

Build and run your project; observe how the field jumps back from its rightmost position with robotic vigor. This looks unnatural and isn’t as visually pleasing as the previous animation.

Finally give .curveEaseInOut a try. It combines the two options you already know into one very natural looking easing. .curveEaseInOut is also the default easing function UIKit applies to your animations.

You’ve seen how the various animation options affect your project and how to make movements look smooth and natural.

Before you move on, change the options on the piece of code you’ve been playing with back to []:

UIView.animate(withDuration: 0.5, delay: 0.4, options: [], 
  animations: {
    self.password.center.x += self.view.bounds.width
  }, 
  completion: nil
)

Where to Go From Here?

You can download the finished project from this tutorial here.

Now that you know how basic animations work, you’re ready to tackle some more dazzling animation techniques.

Animating views from point A to point B? Pshaw – that’s so easy! :]

iAT@2xIf you want to learn more, check out our book iOS Animations by Tutorials. The book has been fully updated for Swift 3 and iOS 10. You’ll learn how to animate with springs, transitions, keyframe animations, CALayer animations, Auto Layout constraint animations, view controller transition animations, and more!

We hope you enjoyed this tutorial, and if you have any questions or comments, please join the forum discussion below!

Marin Todorov

Part of: Realm and raywenderlich.com. Author of books and apps. More: <a href="http://www.underplot.com">www.underplot.com</a>

Other Items of Interest

Save time.
Learn more with our video courses.

raywenderlich.com Weekly

Sign up to receive the latest tutorials from raywenderlich.com each week, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

PragmaConf 2016 Come check out Alt U

Our Books

Our Team

Video Team

... 20 total!

Swift Team

... 15 total!

iOS Team

... 42 total!

Android Team

... 16 total!

macOS Team

... 11 total!

Unity Team

... 11 total!

Articles Team

... 12 total!

Resident Authors Team

... 15 total!