DEV Community

Sebastien Lato
Sebastien Lato

Posted on

Micro-Interactions in SwiftUI — Subtle Animations That Make Apps Feel Premium

Micro-interactions are the tiny animations that make an app feel alive.

They’re not big transitions or hero animations — they’re the small details that signal depth, responsiveness, and craftsmanship.

Apple uses micro-interactions everywhere:

  • button taps
  • icon highlights
  • card lift-on-hover
  • subtle pops
  • ripple effects
  • rotation hints
  • glow pulses

In this post, we’ll build 7 polished micro-interactions using pure SwiftUI.

These are plug-and-play and instantly make your UI feel premium.


🎯 1. Tap Pop Animation (The “Apple Button” Feel)

struct TapPop: View {
    @State private var pressed = false

    var body: some View {
        Text("Tap Me")
            .font(.headline)
            .padding(.horizontal, 26)
            .padding(.vertical, 14)
            .background(.ultraThinMaterial)
            .clipShape(RoundedRectangle(cornerRadius: 16))
            .scaleEffect(pressed ? 0.92 : 1)
            .animation(.snappy(duration: 0.18), value: pressed)
            .onTapGesture {
                pressed = true
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.12) {
                    pressed = false
                }
            }
    }
}
Enter fullscreen mode Exit fullscreen mode

This is the same smooth “tap feedback” feel used in iOS buttons.


🎚 2. Hover Lift / Card Elevation (Like App Store)

struct LiftCard: View {
    @State private var hover = false

    var body: some View {
        RoundedRectangle(cornerRadius: 20)
            .fill(.ultraThinMaterial)
            .frame(height: 140)
            .scaleEffect(hover ? 1.03 : 1)
            .shadow(color: .black.opacity(0.25),
                    radius: hover ? 30 : 10,
                    y: hover ? 10 : 4)
            .animation(.smooth(duration: 0.22), value: hover)
            .onHover { hover = $0 }
    }
}
Enter fullscreen mode Exit fullscreen mode

(Works on iPad, Mac, and VisionOS instantly.)


💫 3. Ripple Effect on Tap

struct RippleButton: View {
    @State private var ripple = false

    var body: some View {
        ZStack {
            Circle()
                .stroke(Color.blue.opacity(0.3), lineWidth: 3)
                .scaleEffect(ripple ? 2.8 : 0.1)
                .opacity(ripple ? 0 : 1)
                .animation(.smooth(duration: 0.55), value: ripple)

            Circle()
                .fill(.blue)
                .frame(width: 70, height: 70)
        }
        .onTapGesture {
            ripple = false
            ripple = true
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Perfect for confirmation taps or action buttons.


🔄 4. Icon Pulse (Subtle Attract Animation)

struct PulsingIcon: View {
    @State private var pulse = false

    var body: some View {
        Image(systemName: "bolt.fill")
            .font(.system(size: 40))
            .scaleEffect(pulse ? 1.08 : 1)
            .animation(.easeInOut(duration: 1.2).repeatForever(), value: pulse)
            .onAppear { pulse = true }
    }
}
Enter fullscreen mode Exit fullscreen mode

Ideal for hinting an interactive element.


🌀 5. Rotation Hint (For Toggles and Arrows)

struct RotateHint: View {
    @State private var rotate = false

    var body: some View {
        Image(systemName: "arrow.triangle.2.circlepath")
            .rotationEffect(.degrees(rotate ? 10 : -10))
            .animation(.smooth(duration: 0.9).repeatForever(autoreverses: true),
                       value: rotate)
            .onAppear { rotate = true }
    }
}
Enter fullscreen mode Exit fullscreen mode

This gently invites interaction.


🌟 6. Glow Pulse Effect (Subtle Neon)

struct GlowPulse: View {
    @State private var glow = false

    var body: some View {
        Circle()
            .fill(.pink)
            .frame(width: 22, height: 22)
            .shadow(color: .pink.opacity(glow ? 0.9 : 0.3),
                    radius: glow ? 20 : 6)
            .animation(.easeInOut(duration: 1.4).repeatForever(autoreverses: true),
                       value: glow)
            .onAppear { glow = true }
    }
}
Enter fullscreen mode Exit fullscreen mode

Looks amazing in glass UIs.


🪄 7. Slide-In Micro Transition (For Cards & Lists)

struct SlideInItem: View {
    @State private var show = false

    var body: some View {
        HStack {
            RoundedRectangle(cornerRadius: 12)
                .fill(.ultraThinMaterial)
                .frame(height: 80)
                .offset(x: show ? 0 : -40)
                .opacity(show ? 1 : 0)
                .animation(.spring(response: 0.4, dampingFraction: 0.75),
                           value: show)
        }
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                show = true
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Great for list appearances and onboarding screens.


✔️ Final Thoughts

Micro-interactions are subtle — but they add:

  • personality
  • polish
  • delight
  • clarity
  • responsiveness
  • “premium feel”

With these reusable SwiftUI patterns, you can upgrade any UI without heavy animation code.

Top comments (0)