SwiftUI withAnimation vs animation Modifier: When to Use Each
Understand when to use withAnimation or animation modifier for SwiftUI animations.
Quick Summary
| Dimension | withAnimation | animation Modifier |
|---|---|---|
| Performance | Similar | Similar |
| Use case | Explicit control | Implicit animation |
| iOS minimum | iOS 13+ | iOS 13+ |
| Complexity | Medium | Low |
| Flexibility | High | Limited |
withAnimation — When to Use
withAnimation is used for explicit animation control in SwiftUI. It allows you to wrap a state change in an animation block, giving you precise control over when the animation occurs. This is useful when you want to animate specific changes in response to user actions or programmatic triggers.
// Using withAnimation
struct ContentView: View {
@State private var isExpanded = false
var body: some View {
VStack {
Button("Toggle") {
withAnimation {
isExpanded.toggle()
}
}
if isExpanded {
Rectangle()
.fill(.blue)
.frame(width: 200, height: 200)
}
}
}
}
animation Modifier — When to Use
The animation(_:value:) modifier is used for implicit animations, meaning the animation is automatically applied whenever the observed value changes. It's simpler to use and ideal for animations that should always occur without manual intervention.
// Using animation modifier
struct ContentView: View {
@State private var isExpanded = false
var body: some View {
VStack {
Button("Toggle") {
isExpanded.toggle()
}
if isExpanded {
Rectangle()
.fill(.blue)
.frame(width: 200, height: 200)
.animation(.easeInOut, value: isExpanded)
}
}
}
}
Side-by-Side Example
Here's a side-by-side implementation of the same animation using both approaches:
// Using withAnimation
struct ContentViewA: View {
@State private var isExpanded = false
var body: some View {
VStack {
Button("Toggle") {
withAnimation {
isExpanded.toggle()
}
}
if isExpanded {
Rectangle()
.fill(.blue)
.frame(width: 200, height: 200)
}
}
}
}
// Using animation modifier
struct ContentViewB: View {
@State private var isExpanded = false
var body: some View {
VStack {
Button("Toggle") {
isExpanded.toggle()
}
if isExpanded {
Rectangle()
.fill(.blue)
.frame(width: 200, height: 200)
.animation(.easeInOut, value: isExpanded)
}
}
}
}
Decision Guide
Use withAnimation when you need explicit control over when the animation runs; use animation(_:value:) when you want implicit, automatic animation on value changes.