How To Make a Table View Drop-In Card Animation

A table view animations tutorial that shows you how to make a drop-in cards animation like in the Google+ app. By Ray Fix.

Leave a rating/review
Save for later
Share

Add some flair to your tables.

Rotate table cell

Add some flair to your tables.

Update note: This tutorial was updated for iOS 8 and Swift by Ray Fix. Updated on 4/12/2015 to support Swift 1.2. Original post by Tutorial Team member Brian Broom and Code Team member Orta Therox.

The standard UITableView is a powerful and flexible way to present data in your apps; chances are that most apps you write will use table views in some form. However, one downside is that without some level of customization, your apps will look bland and blend in with the thousands of apps just like it.

To prevent boring table views, you can add some subtle animation to liven up the actions of your app. You may have seen this in the Google+ app where the cards fly in through the side with a cool animation. If you haven’t seen it yet, download it here (it’s free)! You might also want to check out the design guidelines that Google released at the 2014 I/O conference. It contains many tips and examples on how to use animation well.

In this table view animations tutorial, you’ll be using Swift to enhance an existing app to rotate the cells of a table as you scroll. Along the way, you’ll learn about how transforms are achieved in UIKit, and how to use them in a subtle manner so as not to overwhelm your user with too much happening on-screen at once. You will also get some advice on how to organize your code to keep responsibilities clear and your view controllers slim.

Before beginning, you should know how to work with UITableView and the basics of Swift. If you need an introduction to these topics, you might want to start with the Swift Tutorial series that will teach you the basics of Swift in a table view app.

At publication time, our understanding is we cannot post screenshots of iOS 8 while it’s in beta. Any screenshots shown are from iOS 7, which will be close to what you see in iOS 8.

At publication time, our understanding is we cannot post screenshots of iOS 8 while it’s in beta. Any screenshots shown are from iOS 7, which will be close to what you see in iOS 8.

Getting Started

Download the starter project and open it up in Xcode 6.3. You’ll find a simple storyboard project with a UITableViewController subclass (MainViewController) and a custom UITableViewCell (CardTableViewCell) for displaying team members. You will also find a model class called Member that encapsulates all of the information about a team member and knows how to fetch that information from a JSON file stored in the local bundle.

Build and run the project in the simulator; you’ll see the following:

A perfectly good design, ready to be spiced up.

Starter project

A perfectly good design, ready to be spiced up.

The app is off to a good start, but it could use a little more flair. That’s your job; you’ll use some Core Animation tricks to animate your cell.

Define the Simplest Possible Animation

To get the basic structure of the app going you’ll start by creating a super simple fade-in animation helper class. Go to File\New\File… and select type iOS\Source\Swift File for an empty Swift file. Click Next, name the file TipInCellAnimator.swift and then click Create.

Replace the file contents with the following:

import UIKit

class TipInCellAnimator {
  // placeholder for things to come -- only fades in for now
  class func animate(cell:UITableViewCell) {
    let view = cell.contentView
    view.layer.opacity = 0.1
    UIView.animateWithDuration(1.4) {
      view.layer.opacity = 1
    }
  }
}

This simple class provides a method that takes a cell, gets its contentView and sets the layer’s initial opacity to 0.1. Then, over the space of 1.4 seconds, the code in the closure expression animates the layer’s opacity back to 1.0.

Note: A Swift closure is just a block of code that can also capture external variables. For example, { } is a simple closure. Functions declared with the func keyword are just examples of named closures. It is even perfectly legal to declare functions inside of other functions in Swift.

If you pass a closure as the last argument of a function, you can use the special trailing closure syntax and move the closure outside of the function call. You can see this in the UIView.animateWithDuration() call.

You can read more about closures in the Swift Programming Language book or read about the rich history of closures on Wikipedia.

Note: A Swift closure is just a block of code that can also capture external variables. For example, { } is a simple closure. Functions declared with the func keyword are just examples of named closures. It is even perfectly legal to declare functions inside of other functions in Swift.

If you pass a closure as the last argument of a function, you can use the special trailing closure syntax and move the closure outside of the function call. You can see this in the UIView.animateWithDuration() call.

You can read more about closures in the Swift Programming Language book or read about the rich history of closures on Wikipedia.

Now that you have the animation code ready, you need the table view controller to trigger this new animation as the cells appear.

Trigger the Animation

To trigger your animation, open MainViewController.swift and add the following method to the class:

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
    forRowAtIndexPath indexPath: NSIndexPath) {
  TipInCellAnimator.animate(cell)
}

This method is declared in the UITableViewDelegate protocol and gets called just before the cell is shown on the screen. It calls the TipInCellAnimator‘s class method animate() on each cell as it appears to trigger the animation.

Build and run your app. Scroll through the cards and watch the cells slowly fade in:

SwiftDrop-InFadeAnimation

Getting Fancy with Rotation

Now it’s time to make the app a little more fancy with some animated rotation. This works in the same way as the fade-in animation, except you are specifying both start and end transformations.

Open TipInCellAnimator.swift, and replace its contents with:

import UIKit
import QuartzCore // 1

class TipInCellAnimator {
  class func animate(cell:UITableViewCell) {
    let view = cell.contentView
    let rotationDegrees: CGFloat = -15.0
    let rotationRadians: CGFloat = rotationDegrees * (CGFloat(M_PI)/180.0)
    let offset = CGPointMake(-20, -20)
    var startTransform = CATransform3DIdentity // 2
    startTransform = CATransform3DRotate(CATransform3DIdentity,
        rotationRadians, 0.0, 0.0, 1.0) // 3
    startTransform = CATransform3DTranslate(startTransform, offset.x, offset.y, 0.0) // 4

    // 5
    view.layer.transform = startTransform
    view.layer.opacity = 0.8

    // 6
    UIView.animateWithDuration(0.4) {
      view.layer.transform = CATransform3DIdentity
      view.layer.opacity = 1
    }
  }
}

This time the animation is quicker (0.4 seconds), the fading in is more subtle, and you get a nice rotation effect. The key to the above animation is defining the startTransform matrix and animating the cell back to its natural identity transformation. Let’s dig into that and see how it was done:

  1. This class now requires QuartzCore to be imported because it uses core animation transforms.
  2. Start with an identity transform, which is a fancy math term for “do nothing.” This is a view’s default transform.
  3. Call CATransform3DRotate to apply a rotation of -15 degrees (converted to radians), where the negative value indicates a counter-clockwise rotation. This rotation is around the axis 0.0, 0.0, 1.0; this represents the z-axis, where x=0, y=0, and z=1.
  4. Applying just the rotation to the card isn’t enough, as this simply rotates the card about its center. To make it look like it’s tipped over on a corner, add a translation or shift where the negative values indicate a shift up and to the left.
  5. Set this rotated and translated transform as the view’s initial transform.
  6. Animate the view back to it’s original values.

Notice how you were able to build up the final transformation one step at a time as shown in the image below:

Building up transformations to produce the desired effect.

Building up transformations

Building up transformations to produce the desired effect.

Note: An arbitrary chain of transformations can ultimately be represented by one matrix. If you studied matrix math in school, you may recognize this as multiplication of matrices. Each step multiplies a new transformation until you end up with the final matrix.

You’ll also notice that you’re transforming a child view of the cell, and not the cell itself. Rotating the actual cell would cause part of it to cover the cell above and below it, which would cause some odd visual effects, such as flickering and clipping of the cell. A cell’s contentView contains all of its constituent parts.

Not all properties support animation; the Core Animation Programming Guide provides a list of animatable properties for your reference.

Build and run your application. Watch how the cells tilt into view as they appear!

Rotation of card cell.

Contributors

Ray Fix

Author

Over 300 content creators. Join our team.