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

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
        }
        .padding(50)
        .background(.red)
        .foregroundStyle(.white)
        .clipShape(.circle)
    }
}

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
}

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

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

BUY OUR BOOKS
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.