WWDC24 SALE: Save 50% on all my Swift books and bundles! >>

Creating explicit animations

Paul Hudson    @twostraws   

You’ve seen how SwiftUI lets us create implicit animations by attaching the animation() modifier to a view, and how it also lets us create animated binding changes by adding the animation() modifier to a binding, but there’s a third useful way we can create animations: explicitly asking SwiftUI to animate changes occurring as the result of a state change.

This still doesn’t mean we create each frame of the animation by hand – that remains SwiftUI’s job, and it continues to figure out the animation by looking at the state of our views before and after the state change was applied.

Now, though, we’re being explicit that we want an animation to occur when some arbitrary state change occurs: it’s not attached to a binding, and it’s not attached to a view, it’s just us explicitly asking for a particular animation to occur because of a state change.

To demonstrate this, let’s return to a simple button example again:

struct ContentView: View {   
    var body: some View {
        Button("Tap Me") {
            // do nothing

When that button is tapped, we’re going to make it spin around with a 3D effect. This requires another new modifier, rotation3DEffect(), which can be given a rotation amount in degrees as well as an axis that determines how the view rotates. Think of this axis like a skewer through your view:

  • If we skewer the view through the X axis (horizontally) then it will be able to spin forwards and backwards.
  • If we skewer the view through the Y axis (vertically) then it will be able to spin left and right.
  • If we skewer the view through the Z axis (depth) then it will be able to rotate left and right.

Making this work requires some state we can modify, and rotation degrees are specified as a Double. So, please add this property now:

@State private var animationAmount = 0.0

Next, we’re going to ask the button to rotate by animationAmount degrees along its Y axis, which means it will spin left and right. Add this modifier to the button now:

.rotation3DEffect(.degrees(animationAmount), axis: (x: 0, y: 1, z: 0))

Now for the important part: we’re going to add some code to the button’s action so that it adds 360 to animationAmount every time it’s tapped.

If we just write animationAmount += 360 then the change will happen immediately, because there is no animation modifier attached to the button. This is where explicit animations come in: if we use the withAnimation() function then SwiftUI will ensure any changes resulting from the new state will automatically be animated.

So, put this in the button’s action now:

withAnimation {
    animationAmount += 360

Run that code now and I think you’ll be impressed by how good it looks – every time you tap the button it spins around in 3D space, and it was so easy to write. If you have time, experiment a little with the axes so you can really understand how they work. In case you were curious, you can use more than one axis at once.

withAnimation() can be given an animation parameter, using all the same animations you can use elsewhere in SwiftUI. For example, we could make our rotation effect use a spring animation using a withAnimation() call like this:

withAnimation(.spring(duration: 1, bounce: 0.5)) {
    animationAmount += 360
Save 50% in my WWDC sale.

SAVE 50% To celebrate WWDC24, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

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: 4.9/5

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.