Skip to content

View Transitions

.transition() animates the appearing and disappearing of a View.

When the condition that makes the View (dis)appear changes, an animation needs to be triggered, either via withAnimation {} or .animation(value:), otherwise the .transition() modifier will have no effect (see Animating value changes).

.transition() as last modifier in the if-condition block and a dedicated container around for the .animation() is recommended:

swift
// » SwiftUI Garden
// » https://swiftui-garden.com/Animations/View-Transitions

import SwiftUI

struct ViewTransitionExample: View {
    @State var shapeVisible = false

    var body: some View {
        VStack {
            Toggle("Show shape", isOn: $shapeVisible)

            ZStack {
                if shapeVisible {
                    Capsule()
                        .fill(.blue)
                        .frame(width: 150, height: 60)
                        .transition(.blurReplace)
                }
            }
            .frame(height: 200)
            .animation(.default, value: self.shapeVisible)
        }
        .padding()
    }
}

#Preview {
    ViewTransitionExample()
}

Transitioning by identity change

A handy trick is to use .id() view identity to trigger transitions - if you change the id of a View, SwiftUI will see this as "old View disappeared, new View appeared" and if you do that before .transition, will do transitions accordingly:

swift
// » SwiftUI Garden
// » https://swiftui-garden.com/Animations/View-Transitions

import SwiftUI

struct ViewTransitionByIdExample: View {
    @State var slide = 1

    var body: some View {
        VStack {
            Button("Next slide") {
                self.slide += 1
            }

            ZStack {
                Capsule()
                    .fill((slide % 2 == 0) ? .blue : .red)
                    .overlay {
                        Text("\(slide)")
                    }
                    .frame(width: 150, height: 60)
                    .id(slide)
                    .transition(.blurReplace)
            }
            .frame(height: 200)
            .animation(.default, value: self.slide)
        }
        .padding()
    }
}

#Preview {
    ViewTransitionExample()
}