Mastering SwiftUI Animations: From Basic to Advanced Techniques

George NhariGeorge Nhari
4 min read

Table of contents

SwiftUI makes it easy to add animations to your app, but some developers may find it challenging to achieve fine-grained control over the timing, easing, and other properties of the animations.

  1. Understanding the basics of SwiftUI animations: SwiftUI provides a simple and powerful way to add animations to your views and user interface. The basic structure of a SwiftUI animation is to wrap your view in an animation modifier and specify the animation duration and curve. For example:
struct ContentView: View {
    @State private var isAnimating = false

    var body: some View {
        Circle()
            .scaleEffect(isAnimating ? 2.0 : 1.0)
            .animation(.easeInOut(duration: 1.0))
            .onTapGesture {
                withAnimation {
                    isAnimating.toggle()
                }
            }
    }
}

In this example, we're animating the scale of a circle view using a simple animation modifier, specifying a duration of 1 second and an ease-in-out curve. We're also toggling the isAnimating state property using a tap gesture and the withAnimation function, which automatically applies the animation to any changes to the state property.

  1. Customizing animation curves: While SwiftUI provides several built-in animation curves, such as ease-in-out, ease-in, ease-out, and linear, you can also create your own custom curves using the timingCurve function. For example:
struct ContentView: View {
    @State private var isAnimating = false

    var body: some View {
        Circle()
            .scaleEffect(isAnimating ? 2.0 : 1.0)
            .animation(.timingCurve(0.2, 0.8, 0.6, 1.0, duration: 1.0))
            .onTapGesture {
                withAnimation {
                    isAnimating.toggle()
                }
            }
    }
}

In this example, we're using the timingCurve function to create a custom curve with control points at (0.2, 0.8) and (0.6, 1.0). This creates a smoother animation with a slow start and a fast finish.

  1. Adding delay and repeat options: You can also add a delay or repeat option to your animations using the delay and repeatForever modifiers. For example:
struct ContentView: View {
    @State private var isAnimating = false

    var body: some View {
        Circle()
            .scaleEffect(isAnimating ? 2.0 : 1.0)
            .animation(.easeInOut(duration: 1.0)
                        .delay(0.5)
                        .repeatForever())
            .onTapGesture {
                withAnimation {
                    isAnimating.toggle()
                }
            }
    }
}

In this example, we're using the delay modifier to delay the animation start by 0.5 seconds, and the repeatForever modifier to repeat the animation indefinitely.

  1. Staggering animations: To create more complex animations, you can use the staggered function to add a delay to each view in a list or group. For example:
struct ContentView: View {
    @State private var isAnimating = false

    var body: some View {
        VStack {
            ForEach(0..<5) { index in
                Circle()
                    .scaleEffect(isAnimating ? 2.0 : 1.0)
                    .animation(.easeInOut(duration: 1.0)
                                .delay(Double(index) * 0.2))
            }
        }
        .onTapGesture {
            withAnimation {
                isAnimating.toggle()
            }
        }
    }
}

In this example, we're using the ForEach function to create a list of five circles and using the staggered function to add a delay to each circle based on its index in the list. This creates a staggered animation effect where each circle starts animating with a slight delay.

  1. Using explicit animations: In addition to the implicit animations we've been using so far, SwiftUI also provides the ability to create explicit animations using the withAnimation function. This allows you to specify exactly which properties of your view should be animated, and to customize the animation duration, curve, and other options. For example:
struct ContentView: View {
    @State private var isAnimating = false
    @State private var circleScale: CGFloat = 1.0

    var body: some View {
        Circle()
            .scaleEffect(circleScale)
            .onTapGesture {
                withAnimation(.easeInOut(duration: 1.0)) {
                    circleScale = isAnimating ? 1.0 : 2.0
                }
                isAnimating.toggle()
            }
    }
}

In this example, we're using the withAnimation function to create an explicit animation that animates the circleScale property of our view. We're also specifying a duration of 1 second and an ease-in-out curve. When the user taps the circle, we toggle the isAnimating state property and update the circleScale property within the animation block.

  1. Conclusion: By understanding the basics of SwiftUI animations and customizing animation curves, delays, repeats, staggers, and explicit animations, you can achieve fine-grained control over the animations in your app. Remember to experiment with different combinations of animation options to create the desired effect, and to test your animations on a range of devices to ensure optimal performance.
0
Subscribe to my newsletter

Read articles from George Nhari directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

George Nhari
George Nhari

I am currently an intern, work is actually fun. Especially coding with people. I don't really take pictures, ill upload a profile picture soon ๐Ÿ˜†