UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

How to animate when your size class changes: willTransition(to:)

Swift version: 5.6

Paul Hudson    @twostraws   

A size class change is usually triggered by your user rotating their device, but it can also happen for example when using the new iOS 9.0 multitasking to adjust window splits. Your UI needs to look great in all size classes it supports, which means you either create multiple variations of your layouts inside Interface Builder (this is the preferred route) or you make changes in code.

More often than not, I find myself mixing approaches: I do the vast majority of work inside IB, then make minor changes by hand inside the willTransition(to:) method. When this is called, you'll be given a UIViewControllerTransitionCoordinator object (yes, that's an extremely long name!) to work with, which allows you to animate your changes as needed.

To give you a very visible demonstration of how this works, I've written some example code below that adjusts the background color of the current view. You should run this using the iOS simulator using an iPhone rather than an iPad. The reason that this requires the iPhone simulator rather than the iPad simulator is that iPads have the same size classes in portrait and landscape, which makes the changes harder to spot.

Anyway, put this code into a view controller, then try it on an iPhone. When you rotate the simulator, the screen will change between red and blue, or green and blue, depending on the rotation. The important thing is that the change is animated because it's placed inside a call to animate(alongsideTransition:), which automatically makes your animation match the rotation animation.

Using this method requires two closures: the first is where you make the changes you want to animate, and the second is code to be run when the animation completes. So, when the new vertical size class is compact, the screen will animate from blue to red, then jump back to blue. I realize this isn't directly useful in your own apps, but that's because you'll want to make your own changes – just take the code below and replace the background color changes with your own logic.

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
    super.willTransition(to: newCollection, with: coordinator)

    coordinator.animate(alongsideTransition: { [unowned self] _ in
        if newCollection.verticalSizeClass == .compact {
            self.view.backgroundColor = UIColor.red
        } else {
            self.view.backgroundColor = UIColor.green
    }) { [unowned self] _ in
        self.view.backgroundColor = UIColor.blue

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Available from iOS 8.0

Similar solutions…

About the Swift Knowledge Base

This is part of the Swift Knowledge Base, a free, searchable collection of solutions for common iOS questions.

Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 3.1/5

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.