iOS

Creating Simple View Animations in Swift


Following the release of iOS 7 (and iOS 8 as well), animation and motion effects became central to the design of apps from both Apple and 3rd party developers. iOS 7 introduced a flat, minimal design to apps which inevitably resulted in some apps having a similar UI. To distinguish their apps from other apps, developers employed such features as animations and motion effects to make their apps stand out.

Not only are animations used to set your app apart, they can improve the overall user experience of your application. For great examples of how animations are used to improve UX, you should look at how Apple uses animations in their apps. For example, in the Photos app, when you select a photo from a collection, the photo expands out from the selected one and on closing it, it shrinks back to the selected photo. This adds to the navigation of the app in that it lets you know exactly where you were, if browsing many pictures.

view-animations-featured

Facebook’s Paper also employs animations beautifully to add to the overall user experience of the app. You select an article to read by flipping it up. This action, the fact that the article expands out from its thumbnail version, suggests that in doing the opposite, i.e. flipping the article downwards, would shrink it back to its thumbnail. Here, animation is used to convey how the app works and even a first time user of the app would soon be able to make assumptions on its use and figure out its navigation without needing a tutorial.

Not only do animations add to the user experience of the app, but they could be what delights and impresses your users guaranteeing repeat usage instead of uninstalling the app for a better one from the App Store.

There are numerous ways of including animations in your apps, some of them being by use of UIKit Dynamics, layer animations, view controller transitions or by using a third party library like the Facebook Pop library or JNWSpringAnimation framework.

In this tutorial we are going to look at simple view animations. You can download the starter project which is a Single View Application with a table view that lists the examples presented in the tutorial tutorial. I will be using this when we get to the examples portion of the tutorial, instead of starting from scratch.

The tutorial starts off with a summary of APIs used to animate views, and ends with some examples which show the use of some of the APIs in an app.

Basic View Animations

Creating animations on your views is a matter of changing properties on them and letting UIKit animate them automatically. The properties we change are the ones marked Animatable.

The following list shows the animatable properties.

  • center
  • alpha
  • frame
  • bounds
  • transform
  • backgroundColor
  • contentStretch

You will find that all animations involve a change of one or more of the above properties.

For simple view animations, UIKit provides the following APIs that can be used to animate views on the screen.

  • UIView.animateWithDuration(_:, animations:)
  • UIView.animateWithDuration(_:, animations:, completion:)
  • UIView.animateWithDuration(_:, delay:, options:, animations:, completion:)

The first one takes two parameters – a value for the duration in seconds of the animation and a closure where you specify the properties you want changed. UIKit will take the original state of the view and create a smooth transition from that state to the end state according to what you specified in the animations closure.

The other two APIs are similar to the first, but they take extra parameters that add more configuration to the animation. The second takes a completion closure which you can use to either specify another animation that you want done after the first or you can do some cleanup of the UI, for example, removing a view from the view hierarchy once another view is animated onto the scene.

The third API takes an additional two parameters – the delay, which is the time to wait before the animation starts and options, a UIViewAnimationOptions constant, which indicates how you want to perform the animations. The following shows the options available.

anim_image001

Spring Animations

Spring animations try to model the behaviour of a real life spring, in that, when a view is moved from one point to another, it will bounce/oscillate towards the end before settling down to position.

Below is the method block we use for spring animations.

  • UIView.animateWithDuration(_:, delay:, usingSpringWithDamping:, initialSpringVelocity:, options:, animations:, completion:)

The above is similar to the methods we looked at earlier except for two new parameters – usingSpringWithDamping and initialSpringVelocity. Damping is a value from 0 to 1 that determines how much the view bounces towards the end of the animation. The closer to 1 the value is, the less bouncy it will be. initialSpringVelocity as the name says, determines the initial velocity of the animation. This determines how strong the animation starts off. If you want it to start vigorously, then set a larger value, if you want a smooth animation, then you can set the value to 0.

Keyframe Animations

Keyframe animations enable you to set different stages of an animation. You can group different animations together that share some common properties, but still be able to control them separately.

Instead of an animation that just moves along a path, UIKit will execute the different stages of the animation.

The Keyframe animation APIs are as follows.

  • UIView.animateKeyframesWithDuration(_:, delay:, options:, animations:)
  • UIView.addKeyframeWithRelativeStartTime(_:, relativeDuration:)

The above two methods are used together, the second getting nested in the first’s animations closure.

The first method sets the overall configuration of the animation, like how long it takes, delay and its options. You then define one or more of the second method(the frames) inside the animations closure to set the different stages of the animation.

The relative start time and relative duration of each frame is a value between 0 and 1 that expresses the percentage time within the total duration of the animation.

View Transitions

View transitions are used when you want to add a new view to your view hierarchy or remove a view from the view hierarchy.

The APIs that are used to create view transitions are

  • UIView.transitionWithView(_:, duration:, options:, animations:, completion:)
  • UIView.transitionFromView(_:, toView:, duration:, options:, completion:)

You use the first one to introduce a view to the view hierarchy. The method takes similar parameters as we have seen in the other animation methods.

The second one is used to take one view from the view hierarchy and and place a new view in its place.

Examples

We’ll now look at a few examples that use some of the above API calls to animate views in the given starter project.

Example I

If you run the project, you’ll see a table view that lists the examples we’ll work through. Select Example I in the list and you should see a Login screen of an app with the username and password fields and login button.

We want these to be animated onto the screen when the app starts.

To get started we’ll hide the views from sight when the view first appears. Before Auto Layout, this would have been a simple matter of changing the specific view’s position in code, but since we set auto layout constraints on the views in the storyboard file, we’ll have to change the constraints in code, which will change the view’s position.

First, we need to get a reference of the constraints that we will change. Open the storyboard file. Locate the following constraints in the Example I Scene.

anim_image002

Open the Assistant Editor, and make sure it is the ExampleIViewController.swift that appears next to the storyboard on the split screen. Drag from the Center X Alignment – View – Username constraint to the ExampleIViewController class. Create an outlet named centerAlignUsername. Do the same for the Center X Alignment – View – Password and set its name to centerAlignPassword. Also create an outlet for the login button named loginButton and an action for the same button and name it login. Make sure you set the Type of the action to UIButton. You should have the following in code.

In the ExampleIViewController.swift add the following method which is called before the view is presented on screen.

This moves the username and password fields just out of view and sets the alpha value of the button to 0 which makes it invisible.

Add the following method which is called right when the view appears.

Here we use the UIView.animateWithDuration() method that we saw earlier. We include the UIViewAnimationOptions.CurveEaseOut option which makes the animation start fast then slow down at the end. You can experiment with different options here. Command-click on UIViewAnimationOptions to see all the options available.

The animation lasts for 0.5 seconds and starts immediately. You have liberty over the duration, but you shouldn’t set such a large number as to annoy your users when animations on your app seem to take too long. Normally, the duration is set between 0.5 and 0.7 seconds, but as I said, this isn’t set in stone and you have liberty to set it to whatever feels right to you.

The animation does the exact opposite of what we did in viewWillAppear(). layoutIfNeeded() is used to lay out the views immediately they are changed. If you don’t include it, you will not see them get animated onto the screen, instead they will just be shown in their final position. Run the app, and you should see the following.

video001

The above looks more interesting than a static presentation, but the views getting animated at the same time, doesn’t create that great an effect. Modify the method as shown below.

Run the app and the resulting animation has the views animating on screen at different times. Looking at the code, you can see that after the first animation block, we set a delay on subsequent ones.

video002

In login screens, when login fails, there is usually an animation that indicates to the user that login has failed. This is sometimes done as a shake of the text fields or the login button, and a message that lets the user know that login has failed. We’ll add such an effect on the login button using springs. Modify the login() function as shown.

The above changes the size of the login button when pressed and animates the action with a spring animation which will cause the button’s width to expand and bounce a little at the end before settling.

video003

Play around with the damping value. If you set it to 1, the button will expand, with no bouncing at the end. You can also use the same method on the username and password fields. Instead of having them come onto the screen and just stop in place at the end, have them be spring-like and bounce a little before settling down.

Example II

In your app, you might need to replace the background image of a view automatically when some action happens. You could do it in a way where an image immediately replaces another on the view, or you could slowly fade it in to create a nice transition. We’ll create this effect here. Open ExampleIIViewController.swift and add the following.

Here we create an image view and add it to the main view. We then call imageFadeIn() which creates a second view with a different image. We add this view above the first image view and set its alpha to 0. In the animation block, we animate its alpha value, making it visible. We then use a completion closure to set the image view’s image to the second image and we remove the second image view from the view hierarchy since it is no longer needed. I’ve added a long delay so that the animation doesn’t happen right at the moment we select Example II from the table view. The duration is also a bit long so we can see what’s going on in the demo.

The following is the effect.

videoeg02

Example III

Next we’ll look at keyframe animations. Open ExampleIIIViewController.swift and add the following variable and functions to the file. I’ve commented the code to explain each step.

In viewDidLoad() call the createView() function. Add the following to the bottom of viewDidLoad().

On running the app and selecting Example III from the table view, you should see a red view with an image view at the top and a button in the middle.

anim_image003

We want to have the view(which I’ll refer to as the alertView from now onwards) to shrink in size and fall downwards out of view.

When we created the button, we added a listener to it. When the button is tapped, dismissAlert() is called. Modify the function as shown.

In the above code, we create frames that represent what we want for the two stages of animating the view. smallFrame shrinks to half the size of alertView, maintaining the center point and finalFrame has a position at the bottom of the screen, out of view.

We use a Keyframe animation with two keyframes. The first sets alertView’s frame to smallFrame and the second to finalFrame. The result will be that the alertView will shrink to half its size and then fall out of view. Notice I have put such a large number for the duration – 4 seconds. You can change this, I just wanted the animation running in slow-motion for the demo. Run the app and select Example III.

video004

The animation isn’t quite what we expected. You can see the red alertView animate as expected, but the scale of its children doesn’t change. Changing the parent’s frame, doesn’t automatically change its children’s frames.

We’ll use a feature introduced in iOS 7 called UIView snapshots to fix the animation. This allows you to take a snapshot of a UIView together with its hierarchy and render it into a new UIView.

In dismissAlert() add the following right before the Keyframe animation code.

Here, we create a snapshot view and add it to the main view. We then remove the alertView from view, as the snapshot will replace it.

Replace the Keyframe animation with the following.

Run the application and on tapping Dismiss, the view(snapshot, really) should animate as expected.

video005

Example IV

We’ve looked at how you can animate simple views. In this example we’ll look at how you can animate a table view.

If you select Example IV from the table view, you will find another table view with a list of items in it. When the table view is presented, the list items are already positioned onto the table. We want to animate them onto the view to create a more interesting effect.

video006

Open ExampleIVViewController.swift and add the following methods.

Here, when the view appears, the animateTable() function is called. We reload the table view data and loop through the cells that are currently visible on the screen and move each of them to the bottom of the screen. We then iterate over all the cells that we moved to the bottom of the screen and animate them back to position with a spring animation.

Run the app and you should see the following.

video007

Conclusion

We have looked at various APIs that you can use to add animations to your app’s views. This is not an exhaustive guide on animation in iOS but by using the simple APIs we have looked at, you can create various animations in your apps. To dive further into iOS animations, you could look at UIKit Dynamics, layer animations, view controller transitions and even motion effects. You could also look at third party libraries like Facebook Pop and JNWSpringAnimation framework which could help you build intricate animations more easily.

You can download the completed project here.

As always, leave me comment and share your thought about the tutorial.

Note: This tutorial is also available in Chinese. We’re going to support other languages soon. If you want to join our translation team, please contact us.
Tutorial
Creating an Immersive User Experience with Haptic Feedback in iOS
iOS
Realistic Rendering of 3D Photogrammetry Model in ARKit
iOS
Memory Management in Swift: Understanding Strong, Weak and Unowned References
  • mike

    mikemike

    Author Reply

    How can you do the last animation (Example IV) using objective c?


    • Joyce Echessa

      I haven’t tested this in an IDE, I just went line by line changing Swift to Obj-c, so you might find minor errors or typos. But it should give you an idea of the Obj-c code. I only give the code for the animateTable function, since that’s where all the animation is done. (Disqus is messing up the indentation)

      – (void)animateTable
      {
      [self.tableView reloadData];
      NSArray *cells = [self.tableView visibleCells];
      CGFloat tableHeight = self.tableView.bounds.size.height;

      for (int i = 0; i < [cells count]; i++) {
      UITableViewCell *cell = [cells objectAtIndex:i];
      cell.transform = CGAffineTransformMakeTranslation(0, tableHeight);
      }

      //No need to use index here like in the swift code. We’ll use the for loop's index
      for (int a = 0; a < [cells count]; a++) {
      UITableViewCell *cell = [cells objectAtIndex:a];
      [UIView animateWithDuration:1.5 delay:0.05*a usingSpringWithDamping:0.8 initialSpringVelocity:0 options:0 animations:^{
      cell.transform = CGAffineTransformMakeTranslation(0, 0);
      } completion:NULL];
      }
      }


  • IDesignIT Kungsbacka

    Can’t download starter project. Dropbox says file has been removed.


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      Please try again. I have just updated the link.


  • Geo

    GeoGeo

    Author Reply

    link still not working


    • Simon Ng

      Simon NgSimon Ng

      Author Reply

      Just tested the links again. Both links work. Would you please reload the web page and try again?


  • bcwoodard

    bcwoodardbcwoodard

    Author Reply

    How would you include table header views (for tables with multiple sections) in the animation?


  • Szabolcs Sztányi

    Probably it is better to use CGAffineTransform rather than modifying the bounds or the frame of the view directly.


  • Samuel

    SamuelSamuel

    Author Reply

    Hello!! Thanks for your tutorial and I have a small question about the last example. I’m confused about that if I remove the “cell.transform = CGAffineTransformMakeTranslation(0, 0)” from the animation function, nothing will happen in the tableview, I thought that it will move all the cell but it didn’t? Then what is function of the cell.transform = CGAffineTransformMakeTranslation(0, tableHeight) without the animation? Really thanks for your help, any suggestion is appreciated : )


  • Chris

    ChrisChris

    Author Reply

    Hello.

    How would one go about replicating Example IV for a UICollectionView with UICollectionViewCells?

    I’m most of the way there in Swift 2.0, but this fails at cell.transform = CGAffineTransformMakeTranslation(0, 0)


  • Nick

    NickNick

    Author Reply

    Hi, thanks very much for these tutorials! For example II, is there a way to keep the images rotating? So have the same thing with like 4 images, and when it gets to the last image, it starts from the beginning again? thanks in advance


  • Rob_McB

    Rob_McBRob_McB

    Author Reply

    I’m trying this in a Master Detail template in Xcode 7 beta in Swift 2 but getting the following uncaught exception on startup of the simulator:

    2015-09-10 15:53:16.269 Project1[5221:591432] -[UINavigationItem _setViewDelegate:]: unrecognized selector sent to instance 0x7fb928d171a0

    2015-09-10 15:53:16.273 Project1[5221:591432] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[UINavigationItem _setViewDelegate:]: unrecognized selector sent to instance 0x7fb928d171a0’

    Can anyone offer some advice, I’m completely new to iOS and Swift and not sure what is happening and how to resolve.

    Thanks


  • lanceatlarge

    When I have more than about 8 rows the bottom few cells do not animate into position, they just appear at the bottom of the cells that are animating. Do you know what could be causing this?


  • Curious

    CuriousCurious

    Author Reply

    For the last tableview example, the scrolling stops after cell transformation.


  • Beginner iOS

    Great tutorial! thanks!


  • Abdul Hameed

    Good tutorial for basic animation


  • Juan Felipe Gallo

    Awsome Post! Thorough As ! Thanks very much


  • harsha kiran

    Im having the following error in example iv code nil is not compatible with UIAnimationOptions ? how to clear this error.


  • Jack

    JackJack

    Author Reply

    Thanks for sharing it! I have found nice open source Android Library for making animated tutorials inside your app. Maybe, it would be interesting too: https://github.com/Cleveroad/SlidingTutorial-Android


  • Tiago

    TiagoTiago

    Author Reply

    Great work!!

    And the last example can be used with UICollectionView: https://github.com/tiagoSAmaral/appcodaAnimationUICollection


  • Mohammad Eliass Al husain

    the last animation didn’t work with swift 3 ?


  • Daniel McGlaughlin

    It would be absolutely lovely if you could update this for the current code. Great writeup.


  • Tushar Mohod

    Wow it was nice to implement these animations. Learnt so many things from this. Thanks a lot! Great Work! Keep it up.


Leave a Reply to Tiago
Cancel Reply

Shares