DEV Community

Sebastien Lato
Sebastien Lato

Posted on

SwiftUI Animation Masterclass — Springs, Curves & Smooth Motion

SwiftUI makes animation incredibly easy — but smooth, professional, Apple-quality motion requires a deeper understanding of how timing, springs, and transitions really work.

In this masterclass, we’ll cover everything you need to build clean, fluid, modern animations that match the feel of Apple’s own apps.

This includes:

  • implicit vs explicit animations
  • spring physics
  • timing curves
  • matchedGeometryEffect
  • phase animations
  • interactive gestures + motion
  • real-world patterns you can reuse

Let’s level up your animation game. 🚀


🎯 1. Implicit vs Explicit Animations

Implicit Animation

Changes animate automatically when bound to a state.

@State private var scale = 1.0

Circle()
    .scaleEffect(scale)
    .animation(.easeInOut(duration: 0.4), value: scale)
Enter fullscreen mode Exit fullscreen mode

Just update scale → animation runs.


Explicit Animation

More control — run animation code manually.

withAnimation(.spring(response: 0.35, dampingFraction: 0.8)) {
    scale = 1.4
}
Enter fullscreen mode Exit fullscreen mode

Use explicit when the animation is event-triggered, not view-driven.


🌀 2. The 2026 Animation Curves You Should Use

SwiftUI now includes several curve presets worth mastering:

.easeInOut(duration:)
.linear(duration:)
snappy(duration: , extraBounce:)
smooth(duration:)
spring(response:, dampingFraction:, blendDuration:)
Enter fullscreen mode Exit fullscreen mode

Best general-purpose animation

.snappy(duration: 0.25)
Enter fullscreen mode Exit fullscreen mode

Fast, clean, feels like modern iOS.

For soft UI transitions

.smooth(duration: 0.35)
Enter fullscreen mode Exit fullscreen mode

For lively UI with personality

.spring(response: 0.32, dampingFraction: 0.72)
Enter fullscreen mode Exit fullscreen mode

This is close to Apple Music’s feel.


⚡ 3. Spring Animation Deep Dive

Springs simulate real physics:

response

How quickly the animation reacts
→ lower = faster

dampingFraction

How much bounce it has
→ 0.5 = bouncy
→ 0.9 = soft stabilization

Example:

withAnimation(.spring(response: 0.28, dampingFraction: 0.78)) {
    isOpen.toggle()
}
Enter fullscreen mode Exit fullscreen mode

This creates a smooth card expansion like Apple Wallet.


🔁 4. matchedGeometryEffect — Smooth Between-State Transitions

The most powerful SwiftUI animation tool.

Transforms:

  • position
  • size
  • shape
  • clip
  • opacity

…between two views.

Example:

@Namespace private var anim

if expanded {
    RoundedRectangle(cornerRadius: 22)
        .matchedGeometryEffect(id: "panel", in: anim)
        .frame(height: 300)
} else {
    RoundedRectangle(cornerRadius: 22)
        .matchedGeometryEffect(id: "panel", in: anim)
        .frame(height: 80)
}
Enter fullscreen mode Exit fullscreen mode

This creates Apple-level transitions.


🎚️ 5. Gesture-Driven Interactive Animations

Combine DragGesture with spring animation for natural movement:

@State private var offset: CGFloat = 0

Circle()
    .offset(y: offset)
    .gesture(
        DragGesture()
            .onChanged { offset = $0.translation.height }
            .onEnded { _ in
                withAnimation(.spring(response: 0.3, dampingFraction: 0.8)) {
                    offset = 0
                }
            }
    )
Enter fullscreen mode Exit fullscreen mode

This is the basis of:

  • bottom sheets
  • interactive cards
  • draggable overlays
  • pull-to-expand panels

🟣 6. Phase Animations (Looping & Sequenced)

Great for micro-animations, loading indicators, pulsing effects.

@State private var phase = 0.0

Circle()
    .scaleEffect(1 + 0.05 * sin(phase))
    .onAppear {
        withAnimation(.linear(duration: 1).repeatForever(autoreverses: true)) {
            phase = .pi * 2
        }
    }
Enter fullscreen mode Exit fullscreen mode

Makes components feel alive.


🎬 7. Real-World Animation Pattern: Expanding Card

struct ExpandingCard: View {
    @State private var open = false

    var body: some View {
        VStack {
            if open {
                detail
            } else {
                preview
            }
        }
        .onTapGesture {
            withAnimation(.spring(response: 0.3, dampingFraction: 0.82)) {
                open.toggle()
            }
        }
    }

    var preview: some View {
        RoundedRectangle(cornerRadius: 20)
            .fill(.ultraThinMaterial)
            .frame(height: 120)
            .overlay(Text("Tap to expand"))
    }

    var detail: some View {
        RoundedRectangle(cornerRadius: 20)
            .fill(.ultraThinMaterial)
            .frame(height: 340)
            .overlay(Text("Expanded content"))
    }
}
Enter fullscreen mode Exit fullscreen mode

Clean, expressive, interactive.
Perfect for:

  • dashboards
  • media players
  • settings panels
  • card-based UIs

✔️ Final Thoughts

Smooth motion is one of the most important parts of building apps that feel premium.

Now you have:

  • clean animation architecture
  • tuned springs
  • modern curves
  • interactive gestures
  • matchedGeometry transitions
  • looping micro-animations

Use these patterns and your SwiftUI UIs will instantly feel more like Apple’s own apps.

Top comments (0)