Understanding animation types
There are two types of animations in SwiftUI: implicit and explicit. Let’s look at what these animation types do and the difference between the two.
An implicit animation is an animation that is automatically applied to a property when its value is changed. In SwiftUI, implicit animations are created using the .animation
modifier. Here is an example:
struct ContentView: View { @State private var grow: CGFloat = 1 var body: some View { Circle() .frame(width: 100, height: 100) .foregroundColor(.blue) .onTapGesture { self.grow += 0.5 } .scaleEffect(grow) .animation(.default, value: grow) } }
In this example, we use a tap gesture to scale up the size of a circle; when tapped, the circle will grow by half its size. The .animation
modifier uses the default animation style, which will animate the circle using an easeInOut timing curve by default.
You can also use other animation styles. For example, here, I added a spring
style instead of the default style:
var body: some View { Circle() •••••••• .scaleEffect(grow) .animation(.spring(dampingFraction: 0.3,blendDuration: 0.5),value: grow) }
This style will animate the circle and add a springy effect to it.
So implicit animations are a convenient way to add basic animations to your SwiftUI app without having to write any explicit animation code. The animations are applied using the animation
modifier.
Sometimes though, you may want more from your animation, and implicit animations may not give you the degree of control that you are looking for. In this case, you can use explicit animations instead.
An explicit animation is an animation you create and add inside the code block using the withAnimation
function. Here’s an example:
struct ContentView: View { @State private var scaleUp: CGFloat = 1 var body: some View { Button(action: { //Animate the scale of the view when the button is tapped withAnimation(.interpolatingSpring(stiffness: 60, damping: 2)) { scaleUp *= 1.4 } }) { Text("Scale up") .scaleEffect(scaleUp) // explicit animation } } }
In this example, tapping the button will animate the scale of the text using a spring animation. The duration of the animation will be determined by the system’s default animation settings, but the curve of the animation will be customized using the interpolatingSpring
function.
Additionally, you can customize the duration of the animation by specifying a duration
parameter in the interpolatingSpring
function. The following is an example of this:
withAnimation(.interpolatingSpring(stiffness: 60, damping: 2, duration: 2.5)) { scaleUp *= 1.5 }
This will cause the animation to last for 2.5
seconds.
So, the difference when using explicit animations versus implicit animations is that they can give you more control over the details of the animation, or when you want to animate multiple properties simultaneously; you can put as much code into the withAnimation
block as needed. However, they can be more work to set up than implicit animations.
You can also have the animation repeat itself a pre-set number of times or indefinitely. Here’s an example of repeating the previous animation forever and auto-reversing it:
withAnimation(.interpolatingSpring(stiffness: 60, damping: 2).repeatForever(autoreverses: true)) { scaleUp *= 1.4 }
In the previous example, I altered the code in the withAnimation
function to include the repeatForever
option and set the autoreverses
parameter to true
. When you run the code, the text will scale up with a springy effect, and when it’s done bouncing (about 3 seconds or so), the animation will start over, repeating endlessly or until the app is stopped.
Those are the two types of animations; next is a list of ways to trigger animations.