Micro-Interactions in SwiftUI — 细腻动画让应用更显高端

发布: (2025年11月30日 GMT+8 11:45)
4 分钟阅读
原文: Dev.to

SwiftUI 中的微交互

微交互是让应用“有活力”的细小动画。它们不是大型转场或主角动画——而是那些传递层次感、响应性和工艺感的细节。

Apple 在各处都使用微交互:

  • 按钮点击
  • 图标高亮
  • 悬停时卡片提升
  • 细微弹出
  • 涟漪效果
  • 旋转提示
  • 发光脉冲

在本文中,我们将使用纯 SwiftUI 构建 7 个精致的微交互。这些交互即插即用,能立刻让你的 UI 具备高级感。

点击弹出

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
                }
            }
    }
}

这再现了 iOS 按钮中常见的平滑“点击反馈”感受。

提升卡片

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 }
    }
}

在 iPad、Mac 和 Vision OS 上都能立即生效。

涟漪按钮

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
        }
    }
}

非常适合作为确认点击或操作按钮的视觉反馈。

脉冲图标

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 }
    }
}

用于暗示交互元素的存在感。

旋转提示

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 }
    }
}

轻柔地邀请用户进行交互。

发光脉冲

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 }
    }
}

在玻璃质感的 UI 中效果尤佳。

滑入项

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
            }
        }
    }
}

非常适合列表出现或引导页的呈现。

为什么微交互很重要

  • 个性
  • 打磨感
  • 惊喜感
  • 清晰度
  • 响应性
  • “高级感”

使用这些可复用的 SwiftUI 模式,你可以在不编写繁重动画代码的情况下,轻松提升任何 UI 的品质。

Back to Blog

相关文章

阅读更多 »

第1276天:职业攀升

星期六 在前往车站之前,我在当前的副项目上写了一些代码。取得了相当不错的进展,然后该出发了。Made i...

无状态 AI 应用背后的架构

项目一开始就做了一个看似冒险的决定:不使用后端数据库。当时并不需要持久化用户数据——获取用户的响应就是……

失去信心

请提供您希望翻译的文章摘录或摘要文本,我才能为您进行简体中文翻译。