It’s day 32 of the 100 Days of SwiftUI! Yesterday, we finished our Word Scramble project and completed a few challenges. Today, we’re diving into project number 6, which will be another technique project. We won’t be making an app, but we’ll be learning about important SwiftUI features. The focus will be on adding animations. Let’s dive in!
Introduction to animations in SwiftUI
SwiftUI features a range of animations that can be implemented into our apps. They serve a few purposes. One of them is being aesthetically pleasing, making our apps more appealing to the eye. That’s quite important in today’s day and age.
However, animations are also used to show the user the flow of information. If one View
slides in over another, it’s clear to our user what has happened. If it was just to disappear, it would look a bit jarring and might leave the user wondering if that was supposed to happen.
Implicit animations
The simplest type of animation in SwiftUI is an implicit animation. In essence, we let our views know ahead of time what to do if they’re being animated. Implicit animations always need to watch a particular value, similarly to an alert. This ensures they are only triggered when required.
In the example below, we create a Button
that gets bigger every time it’s tapped. To control this behaviour, we need an @State
property.
@State private var animationAmount = 1.0
Button("Tap Me") {
animationAmount += 1
}
.padding(50)
.background(.red)
.foregroundColor(.white)
.clipShape(Circle())
.scaleEffect(animationAmount)
.animation(.default, value: animationAmount)
.blur(radius: (animationAmount - 1) * 3)
Customizing animations
When we attach the
Paul Hudson, Hacking With Swift (@twostraws)animation()
modifier to a view, SwiftUI will automatically animate any changes that happen to that view using whatever is the default system animation, whenever the value we’re watching changes. In practice, that is an “ease in, ease out” animation, which means iOS will start the animation slow, make it pick up speed, then slow down as it approaches its end. We can control the type of animation used by passing in different values to the modifier.
Button("Tap me") {
// animationAmount+=1
}
.padding(50)
.background(.red)
.foregroundColor(.white)
.clipShape(Circle())
.overlay(
Circle()
.stroke(.red)
.scaleEffect(animationAmount)
.opacity(2 - animationAmount)
.animation(
.easeInOut(duration: 2)
.repeatForever(autoreverses: false),
value: animationAmount
)
Animating bindings
The
Paul Hudson, Hacking With Swift (@twostraws)animation()
modifier can be applied to any SwiftUI binding, which causes the value to animate between its current and new value. This even works if the data in question isn’t really something that sounds like it can be animated, such as a Boolean – you can mentally imagine animating from 1.0 to 2.0 because we could do 1.05, 1.1, 1.15, and so on, but going from “false” to “true” sounds like there’s no room for in between values.
struct ContentView: View {
@State private var animationAmount = 1.0
var body: some View {
VStack {
Stepper("Scale amount", value: $animationAmount.animation(), in: 1...10) // Applies the animation any time the value changes
Spacer()
Button("Tap Me") {
animationAmount += 1
}
.padding(40)
.background(.red)
.foregroundColor(.white)
.clipShape(Circle())
.scaleEffect(animationAmount)
}
}
}
Explicit animations
You’ve seen how SwiftUI lets us create implicit animations by attaching the
Paul Hudson, Hacking With Swift (@twostraws)animation()
modifier to a view, and how it also lets us create animated binding changes by adding theanimation()
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.
Button("Tap me") {
withAnimation(.interpolatingSpring(stiffness: 5, damping: 1)) {
rotationAmount += 360
}
}
.padding(50)
.background(.red)
.foregroundColor(.white)
.clipShape(Circle())
.rotation3DEffect(.degrees(rotationAmount), axis: (x: 0, y: 1, z: 0))
And that’s it for day 32! It’s quite easy to add very nice looking animations to our apps and this has already given me a few ideas on how to expand on our past projects to see if I can implement them on my own as well. Tomorrow, we’ll dive even further into animations with more advanced features that SwiftUI provides us with. We keep marching on!
100 Days of SwiftUI – Day 32