How to Animate Table View Cells in iOS: Fade-In, Rotation & Fly-In Effects

Animate table view cells in iOS using the tableView(_:willDisplay:forRowAt:) delegate method with UIView animations and CATransform3D. Core Animation handles all frame interpolation between starting and ending states. You define the initial cell state before it appears on screen, then animate to the final state. The cell has not been drawn yet, so the user never sees a visual flash from the initial position.

Which Delegate Method Triggers Cell Animation

The willDisplay delegate method fires right before a cell becomes visible:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // Set initial state and animate
}

This method is the ideal hook for all entry animations. The cell exists in memory but has not rendered on screen. Any visual properties you set before the animation block become the unseen starting state.

How to Create a Fade-In Animation

Set the cell alpha to zero and animate to full opacity:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cell.alpha = 0
    UIView.animate(withDuration: 1.0, animations: { cell.alpha = 1 })
}

Four lines of code produce a smooth fade-in effect. Core Animation interpolates between alpha 0 (completely transparent) and alpha 1 (fully opaque). The one-second duration gives a natural feel that does not distract the user.

How to Create a Rotation Effect with CATransform3D

Use CATransform3DMakeRotation to rotate cells as they appear:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    let rotationAngleInRadians = 90.0 * CGFloat(Double.pi / 180.0)
    let rotationTransform = CATransform3DMakeRotation(rotationAngleInRadians, 0, 0, 1)
    cell.layer.transform = rotationTransform
    
    UIView.animate(withDuration: 1.0, animations: {
        cell.layer.transform = CATransform3DIdentity
    })
}

CATransform3DMakeRotation takes four parameters. The angle in radians uses 90 degrees converted to 90 times pi divided by 180. X-axis and Y-axis receive zero for no rotation around those axes. Z-axis receives 1 for rotation around the axis pointing out of the screen. The identity matrix CATransform3DIdentity represents the normal untransformed state. Animating from the rotation transform back to identity creates a cards-being-dealt effect.

Understanding CATransform3D Matrix

CATransform3D is a 4x4 matrix that represents a 3D transformation in Core Animation. Apply it to any CALayer transform property to manipulate how the layer appears in 3D space. Apple provides convenience functions for rotation, translation, and scaling. You do not need to understand matrix math to use these APIs. The identity matrix restores the default state.

How to Create a Fly-In Effect with CATransform3DTranslate

Replace rotation with translation for a sliding motion:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    let translationTransform = CATransform3DTranslate(CATransform3DIdentity, -500, 100, 0)
    cell.layer.transform = translationTransform
    
    UIView.animate(withDuration: 1.0, animations: {
        cell.layer.transform = CATransform3DIdentity
    })
}

CATransform3DTranslate moves the cell 500 points left and 100 points down from its final position. The negative X value shifts it left. The positive Y shifts it down. During animation, each cell flies in from off-screen.

How to Combine Multiple Animation Effects

Set multiple properties before the animation block:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cell.alpha = 0
    cell.layer.transform = CATransform3DMakeRotation(90.0 * .pi / 180.0, 0, 0, 1)
    
    UIView.animate(withDuration: 0.8) {
        cell.alpha = 1
        cell.layer.transform = CATransform3DIdentity
    }
}

This creates a rotating fade-in effect. The cell spins into view while simultaneously becoming opaque. Experiment with different combinations of alpha, rotation, translation, and scale transforms.

How to Control Animation Frequency

The willDisplay method fires every time a cell appears, including when scrolling back up. Use a Set to track animated rows:

var hasAnimated = Set<Int>()

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    guard !hasAnimated.contains(indexPath.row) else { return }
    hasAnimated.insert(indexPath.row)
    
    cell.alpha = 0
    UIView.animate(withDuration: 0.5) {
        cell.alpha = 1
    }
}

Set provides lightweight O(1) lookup and insertion. Reset the set in viewDidLoad or whenever the data reloads.

How to Create Staggered Wave Animations

Add a delay based on the index path row:

let delay = Double(indexPath.row) * 0.05
UIView.animate(withDuration: 0.5, delay: delay, options: [], animations: {
    cell.alpha = 1
    cell.layer.transform = CATransform3DIdentity
}, completion: nil)

Each cell animates 0.05 seconds after the previous one. This creates a cascading wave effect that draws the eye down the list.

How to Use Spring Animations for Natural Motion

Use UIView.animate with spring damping:

UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: [], animations: {
    cell.alpha = 1
    cell.layer.transform = CATransform3DIdentity
}, completion: nil)

Spring animations add bounce to make cells feel physical. Lower damping values closer to 0 produce more bounce. Higher values closer to 1 produce less bounce.

Performance Considerations for Cell Animations

Keep animations at 60 frames per second. Set animation durations between 0.3 and 0.6 seconds for optimal feel. Animate only layer properties such as alpha and transform. These properties are GPU-accelerated through Core Animation. Avoid animating frame or bounds on table cells. These trigger CPU-based layout passes that degrade scrolling performance. Stagger animations with small delays to distribute GPU work across frames.

Summary

This tutorial covered the complete implementation process from setup to working code. You now have a functional implementation that you can extend and customize for your own projects. The same patterns apply to related features in the iOS ecosystem.

Frequently Asked Questions

What are the prerequisites for this tutorial? You need Xcode installed on a Mac and basic familiarity with Swift programming. No prior experience with the specific framework is required.

All articles