mcpField
S
swiftui-animation

swiftui-animation

github.com/jamesrochabrun设计与 UI225567 次安装41 周前更新
代码仓库

关于 swiftui-animation

swiftui-animation 是面向开发者的指导技能,帮助在 SwiftUI 中实现进阶动画和 Metal 着色器效果。内容兼顾实现模式,以及动效、无障碍、平台适配和性能建议。

主要功能

  1. 01动画曲线与弹簧效果
  2. 02视图转场与匹配几何效果
  3. 03PhaseAnimator 和 KeyframeAnimator
  4. 04Metal 着色器集成
  5. 05动效无障碍与平台指导
  6. 06动画性能建议

适用场景

  1. 01构建多阶段 SwiftUI 动画
  2. 02创建视图间的英雄转场
  3. 03添加 GPU 着色器效果
  4. 04检查动效的无障碍性与性能

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jamesrochabrun/skills --skill swiftui-animation

安装后在 Claude Code 中输入/swiftui-animation确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
animations.md
metal-shaders.md
motion-guidelines.md
transitions.md

详细介绍

SwiftUI 动画专家

为实现高级 SwiftUI 动画和 Metal 着色器集成提供专家指导。涵盖动画曲线、弹簧、转场、匹配几何效果、PhaseAnimator、KeyframeAnimator 和 GPU 加速着色器效果。

何时使用此技能

  • 理解运动设计原则,以及何时使用动画
  • 让动画易于访问并符合平台特性
  • 在 SwiftUI 中实现动画(弹簧、缓动、关键帧)
  • 创建视图转场(淡入淡出、滑动、缩放、自定义)
  • 使用 matchedGeometryEffect 构建 Hero 动画
  • 使用 Metal 着色器添加 GPU 加速效果
  • 优化动画性能
  • 创建多阶段编排动画

快速参考

动画基础
// Explicit animation (preferred)
withAnimation(.spring(response: 0.4, dampingFraction: 0.75)) {
    isExpanded.toggle()
}

// iOS 17+ spring presets
withAnimation(.snappy) { ... }  // Fast, small bounce
withAnimation(.smooth) { ... }  // Gentle, no bounce
withAnimation(.bouncy) { ... }  // More bounce
常见转场
// Basic
.transition(.opacity)
.transition(.scale)
.transition(.slide)
.transition(.move(edge: .bottom))

// Combined
.transition(.move(edge: .trailing).combined(with: .opacity))

// Asymmetric
.transition(.asymmetric(
    insertion: .move(edge: .bottom),
    removal: .opacity
))
匹配几何效果
@Namespace var namespace

// Source view
ThumbnailView()
    .matchedGeometryEffect(id: "hero", in: namespace)

// Destination view
DetailView()
    .matchedGeometryEffect(id: "hero", in: namespace)
Metal 着色器效果(iOS 17+)
// Color manipulation
.colorEffect(ShaderLibrary.invert())

// Pixel displacement
.distortionEffect(
    ShaderLibrary.wave(.float(time)),
    maxSampleOffset: CGSize(width: 20, height: 20)
)

// Full layer access
.layerEffect(ShaderLibrary.blur(.float(radius)), maxSampleOffset: .zero)

参考资料

详细文档位于 references/:

  • motion-guidelines.md - HIG 运动设计原则

    • 目标明确的运动设计理念
    • 无障碍要求
    • 平台特定注意事项(iOS、visionOS、watchOS)
    • 应避免的动画反模式
  • animations.md - 完整的动画 API 指南

    • 隐式动画与显式动画
    • 弹簧参数和预设
    • 动画修饰符(速度、延迟、重复)
    • 用于多步序列的 PhaseAnimator
    • 用于属性专属时间线的 KeyframeAnimator
    • 自定义可动画属性
  • transitions.md - 视图转场指南

    • 内置转场(透明度、缩放、滑动、移动)
    • 组合转场和非对称转场
    • 匹配几何效果的实现
    • Hero 动画模式
    • 内容转场(iOS 17+)
    • 创建自定义转场
  • metal-shaders.md - GPU 着色器集成

    • SwiftUI 着色器修饰符(colorEffect、distortionEffect、layerEffect)
    • 编写 Metal 着色器函数
    • 使用 UIViewRepresentable 嵌入 MTKView
    • 跨平台 Metal 集成(iOS/macOS)
    • 性能注意事项

常见模式

可展开卡片
struct ExpandableCard: View {
    @State private var isExpanded = false

    var body: some View {
        VStack {
            RoundedRectangle(cornerRadius: isExpanded ? 20 : 12)
                .fill(.blue)
                .frame(
                    width: isExpanded ? 300 : 150,
                    height: isExpanded ? 400 : 100
                )
        }
        .onTapGesture {
            withAnimation(.spring(response: 0.35, dampingFraction: 0.75)) {
                isExpanded.toggle()
            }
        }
    }
}
列表项显示
ForEach(Array(items.enumerated()), id: \.element.id) { index, item in
    ItemRow(item: item)
        .transition(.asymmetric(
            insertion: .move(edge: .trailing).combined(with: .opacity),
            removal: .move(edge: .leading).combined(with: .opacity)
        ))
        .animation(.spring().delay(Double(index) * 0.05), value: items)
}
脉冲指示器
Circle()
    .fill(.blue)
    .frame(width: 20, height: 20)
    .scaleEffect(isPulsing ? 1.2 : 1.0)
    .opacity(isPulsing ? 0.6 : 1.0)
    .onAppear {
        withAnimation(.easeInOut(duration: 1.0).repeatForever(autoreverses: true)) {
            isPulsing = true
        }
    }

最佳实践

  1. 运动应有明确目的 - 不要为了动画而添加动画;应辅助体验,而不是喧宾夺主
  2. 让运动效果可选 - 辅以触觉反馈和音频;切勿只用运动效果传达信息
  3. 力求简洁 - 简短、精准的动画显得轻盈,并能有效传达信息
  4. 优先使用显式动画 - 为清晰起见,使用 withAnimation 而非 .animation() 修饰符
  5. 使用弹簧动画 - 这类动画感觉更自然,也更符合 iOS 风格
  6. 从 .spring(response: 0.35, dampingFraction: 0.8) 开始 - 适用于大多数交互的良好默认值
  7. 将动画时长控制在 400ms 以内 - 更长的动画会显得迟缓
  8. 允许用户取消运动效果 - 不要强迫用户等待动画结束
  9. 在设备上测试 - 模拟器的动画时序有所不同
  10. 分析着色器性能 - 复杂效果的 GPU 耗时至关重要

故障排除

动画不起作用
  • 确保状态更改由 withAnimation 包裹
  • 检查属性是否可动画
  • 确认视图确实发生了变化
匹配几何效果发生跳变
  • 两个视图必须使用相同的 ID 和命名空间
  • 切换时使用显式 withAnimation
  • 检查 zIndex,确保图层顺序正确
着色器未显示
  • 确认 .metal 文件已添加到目标
  • 检查着色器函数签名是否符合预期格式
  • 确保为扭曲效果正确设置 maxSampleOffset

评论

支持 Markdown