mcpField
I
ios-animation-implementation

ios-animation-implementation

github.com/existential-birds开发8565 次安装11 周前更新
代码仓库

关于 ios-animation-implementation

面向 iOS 开发者的动画实现技能,指导使用 Apple 框架编写动画。内容涵盖 API 选择、辅助功能、可中断性和性能,并按任务提供参考文件。

主要功能

  1. 01动画 API 选择指导
  2. 02SwiftUI、UIKit 与 Core Animation 模式
  3. 03减少动态效果与反馈指导
  4. 04可中断性和性能检查
  5. 05按任务分类的动画参考

适用场景

  1. 01为自定义转场选择 API
  2. 02添加手势驱动动画
  3. 03支持减少动态效果设置
  4. 04检查动画性能风险

安装

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

$npx skills add https://github.com/existential-birds/beagle --skill ios-animation-implementation

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

包含的文件

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

references/
core-animation.md
gesture-animations.md
swiftui-animations.md
transitions.md

详细介绍

iOS 动画实现

编写直接使用 Apple 框架的动画代码。第三方动画库会增加依赖风险,而且往往落后于新的 OS 版本;Apple 的 API 针对渲染管线进行了充分优化,并且每个 iOS 版本都会带来免费改进。

编写自定义动画之前

先检查系统是否已经处理了你需要的动效。Apple 的 HIG 指出:“许多系统组件都自动包含动效,让你能在整个 App 中提供熟悉且一致的体验。”系统组件还会自动根据辅助功能设置和输入方式进行调整——Liquid Glass(iOS 26)对直接触控的反馈更明显,而对触控板则会产生较柔和的效果。自定义动画无法免费获得这种适应性,因此系统提供了动效时,优先使用系统动效。

以下情况跳过自定义动画:

  • 标准导航转场已能满足需求(push、pop、sheet、fullScreenCover)
  • SF Symbol 的 .symbolEffect 已能提供所需反馈
  • .contentTransition(.numericText) 已能处理数据变化
  • withAnimation 的系统默认弹簧效果已足够

以下情况编写自定义动画:

  • 系统未提供所需的空间关系(英雄转场、自定义手势)
  • 需要协调多个属性的编排
  • 动画是定义 App 特征的标志性时刻
  • 手势驱动的交互需要自定义进度映射

API 选择

根据需求选择合适的 API。从 SwiftUI 动画(最简单、声明性最强)开始,需要交互控制时再使用 UIKit,只有需要图层级精度时才使用 Core Animation。

需求API原因
状态驱动的属性变化withAnimation / .animation(_:value:)声明式、自动插值
多步骤序列动画PhaseAnimator离散阶段,可为每个阶段单独设置时长
按属性控制时间线KeyframeAnimator每个属性都有独立的关键帧轨道
视图间的英雄转场matchedGeometryEffect + Namespace跨视图身份匹配几何形状
带缩放效果的导航 push/pop.navigationTransition(.zoom)iOS 18+ 内置缩放转场
自定义视图插入/移除遵循 Transition 协议基于 TransitionPhase 的修饰符
视图内内容切换.contentTransition()数字文本、插值、不透明度
基于滚动位置的效果.scrollTransition由阶段驱动的滚动联动动画
SF Symbol 动画.symbolEffect()弹跳、脉冲、摆动、呼吸、旋转
交互式/可中断动画(UIKit)UIViewPropertyAnimator暂停、继续、反转、拖动进度
按图层设置属性动画CABasicAnimation / CASpringAnimation阴影、边框、cornerRadius 动画
复杂动画编排(图层)CAKeyframeAnimation + CAAnimationGroup多属性图层动画
物理模拟UIDynamicAnimator重力、碰撞、吸附、连接
与动画配套的触觉反馈.sensoryFeedback 修饰符与值变化关联
动画背景渐变MeshGradient由定位并动态变化的颜色组成的二维网格

按类别实现

详细模式和代码示例位于参考文件中。加载与你的任务相符的文件:

任务参考
SwiftUI 声明式动画(withAnimation、弹簧、阶段、关键帧)references/swiftui-animations.md
视图转场(导航、模态、自定义 Transition 协议)references/transitions.md
手势驱动的交互式动画references/gesture-animations.md
Core Animation 和 UIKit 动画模式references/core-animation.md

何时加载参考资料

  • 编写 withAnimation、弹簧参数、PhaseAnimator 或 KeyframeAnimator → swiftui-animations.md
  • 构建导航转场、模态呈现、matchedGeometryEffect 或自定义 Transition → transitions.md
  • 实现拖动关闭、滑动操作、捏合/旋转或滚动联动效果 → gesture-animations.md
  • 使用 CABasicAnimation、UIViewPropertyAnimator、图层动画,或桥接 SwiftUI↔UIKit → core-animation.md

弹簧参数速查

弹簧是现代 SwiftUI 中默认的动画类型。使用 duration 和 bounce,不要使用质量/刚度/阻尼参数,除非要桥接到 UIKit/CA。

预设时长弹跳用例
.smooth0.50.0默认转场、大多数状态变化
.snappy0.30.15微交互、切换控件、快速反馈
.bouncy0.50.3俏皮时刻、吸引注意力
.interactiveSpring0.150.0手势跟踪、跟随拖动
自定义不定不定.spring(duration: 0.4, bounce: 0.2)

无障碍与多模态反馈

Apple 的 HIG:“让动态效果可选”,并“通过触觉和音频等替代方式补充视觉反馈,以传达信息”。每个动画都必须处理减少动态效果设置,重要的状态变化应使用多种反馈渠道,而不能只依赖动画。

@Environment(\.accessibilityReduceMotion) private var reduceMotion

// Pattern 1: Conditional animation
withAnimation(reduceMotion ? .none : .spring()) {
    isExpanded.toggle()
}

// Pattern 2: Simplified alternative
.animation(reduceMotion ? .easeOut(duration: 0.15) : .spring(duration: 0.5, bounce: 0.3), value: isActive)

// Pattern 3: Skip entirely
if !reduceMotion {
    view.phaseAnimator(phases) { /* ... */ }
}

减少动态效果时的替代选项(从最自然到最直接):

  1. 交叉淡化 — 用不透明度转场替代动态效果
  2. 缩短时长 — 保持相同动画,但显著加快(0.1–0.15s),不添加弹跳
  3. 即时切换 — 使用 .animation(.none) 或完全跳过动画代码块

取消与可中断性

Apple 的 HIG:“不要让人们必须等待动画播放完毕才能进行任何操作,尤其是他们需要多次体验该动画时。”每个动画都必须可中断。

  • 弹簧动画会自动调整目标值——这是默认行为,几乎总是你想要的效果
  • 对于手势驱动的动画,始终由用户掌控——允许他们在动画进行中取消
  • 对于按序播放的动画(KeyframeAnimator、带触发器的 PhaseAnimator),确保播放期间 UI 仍可交互
  • 除非有关键原因(例如确认破坏性操作),否则不要在动画期间禁用用户交互

性能检查清单

  • 尽可能在渲染服务端运行动画——Core Animation 在主线程之外运行,SwiftUI 的 drawingGroup() 会将渲染转移到 Metal
  • 避免为视图标识变化设置动画(.id() 修饰符)——这会销毁并重新创建视图
  • 当父视图几何变化导致子视图布局在动画期间出现异常时,使用 geometryGroup()
  • 为阴影动画提供显式的 shadowPath——否则系统会在每一帧重新计算路径
  • 在列表和滚动视图中,避免为每个项目添加模糊/阴影动画——这会导致每个单元格都进行屏幕外渲染
  • 保持 PhaseAnimator 和循环动画轻量——它们会持续运行
  • 对于频繁交互,优先使用系统提供的动画,而非自定义动态效果——Apple 的 HIG:“通常应避免为频繁发生的 UI 交互添加动态效果”
  • 使用 Instruments →“Animation Hitches”模板分析,找出帧丢失问题

门禁(标记工作完成前)

按顺序运行;满足每项通过条件后,才能将任务视为完成。

  1. API 匹配 — 根据此任务,从 API 选择表中选择机制。**通过:**你可以用一句话说明应用了哪一行“需求”和哪个 API,而不是“仅仅因为”想用不同层级。
  2. 减少动态效果 — 自定义时序必须遵循“无障碍与多模态反馈”。**通过:**非平凡动态效果会根据 accessibilityReduceMotion 分支处理(或者你只使用系统默认设置/未使用自定义时序)。
  3. 可中断性 — 符合“取消与可中断性”。**通过:**没有对整个动画一概使用 allowsHitTesting(false),除非任务明确要求这样做,并且有简短注释说明原因。
  4. 高负载或连续动态效果 — 循环、始终开启的 PhaseAnimator、逐单元格模糊/阴影,或其他性能检查清单中的警示项。**通过:**你运行了 Instruments(Animation Hitches)并记录了说明或追踪文件路径,或者你先简化了这种模式,并能指出所做的更改。

评论

支持 Markdown