name: ios-animations description: 对齐诊所架构的 iOS 动画工艺指南,适用于 SwiftUI (iOS 26 / Swift 6.2),涵盖运动令牌、弹簧物理、手势连续性、空间过渡、微交互和可访问性。强制在动画视图上使用 @Equatable,并保持动画状态与域/数据功能边界对齐。在诊所模块化 MVVM-C 架构下编写、审查或重构 SwiftUI 动画代码时使用。
dot-skills — Airbnb iOS SwiftUI 动画最佳实践
针对 SwiftUI iOS 26 / Swift 6.2 应用的严格动画工艺指南。包含 8 个类别的 50 条规则,按影响优先级排序。源自 Airbnb Engineering 运动模式、Apple WWDC 会话和 Apple 人机界面指南。强制在每个动画视图上使用 @Equatable,所有弹簧/时间值的运动令牌,以及布局的设计系统令牌。
强制架构对齐
此技能设计为与 swift-ui-architect 和 ios-design-system 一起工作。所有代码示例遵循相同的不可协商约束:
- 每个视图上的
@Equatable宏(Airbnb 测量显示 15% 滚动卡顿减少) - 对于涉及业务逻辑触发的复杂动画状态,使用
@Observable - 对于视图拥有的动画状态(切换布尔值、拖动偏移),使用
@State - 设计系统令牌:
Spacing.xs/sm/md/lg,Radius.sm/md/lg— 零硬编码布局数字 - 运动令牌:
Motion.standard/responsive/playful— 零分散弹簧字面量 - 语义颜色:
.backgroundSurface,.accentPrimary— 视图中无原始 Color 字面量 - 功能动画保持仅表示层;数据/网络问题留在数据包中
范围与兄弟技能关系
此技能是运动层 — 它教导如何构建流畅、高性能的动画。当与兄弟技能一起加载时:
| 兄弟技能 | 其焦点 | 此技能的焦点 |
| swift-ui-architect | 架构(模块化 MVVM-C、路由外壳、协议边界) | 动画架构(运动令牌、弹簧选择、编排) |
| ios-design-system | 设计系统基础设施(令牌、样式、治理) | 运动令牌和动画组件模式 |
| ios-hig | HIG 合规 模式 | 运动特定 HIG(减少运动、空间连续性) |
超出范围: 设计师创作的矢量动画(使用 Lottie 用于 After Effects 导出)。复杂的 UIKit 过渡控制器(参见 Airbnb 的声明式过渡框架)。此技能仅涵盖编程式 SwiftUI 动画。
诊所架构契约 (iOS 26 / Swift 6.2)
此技能中的所有指导假设诊所模块化 MVVM-C 架构:
- 功能模块仅导入
Domain+DesignSystem(从不Data,从不兄弟功能) - 应用目标是汇聚点,拥有
DependencyContainer、具体协调器和路由外壳布线 Domain保持纯 Swift,并定义模型加上仓库、*Coordinating、ErrorRouting和AppError契约Data拥有 SwiftData/网络/同步/重试/后台 I/O 并实现 Domain 协议- 读/写流默认使用陈旧-重新验证读取和乐观排队写入
- ViewModels 直接调用仓库协议(无默认用例/交互器层)
何时应用
在以下情况下参考这些指南:
- 向 SwiftUI 视图或过渡添加动画
- 构建手势驱动的交互(拖动、滑动、平移)
- 使用空间过渡连接视图(展开/折叠、导航变形)
- 设计微交互(按钮按压、切换、加载状态)
- 使内容更改感觉物理(数字滚动、符号替换)
- 编排多元素动画序列(KeyframeAnimator, PhaseAnimator)
- 为设计系统定义运动令牌
- 审查动画代码的性能、可访问性和架构合规性
规则类别按优先级
| 优先级 | 类别 | 影响 | 前缀 | 规则数 |
| 1 | 弹簧物理 | 关键 | spring- | 8 |
| 2 | 时间与感觉 | 关键 | feel- | 6 |
| 3 | 手势连续性 | 高 | gesture- | 7 |
| 4 | 空间过渡 | 高 | spatial- | 6 |
| 5 | 微交互 | 高 | micro- | 6 |
| 6 | 编排 | 高 | orch- | 5 |
| 7 | 工艺与打磨 | 高 | craft- | 5 |
| 8 | 内容运动 | 中高 | content- | 5 |
快速参考
1. 弹簧物理 (关键)
spring-motion-tokens— 将所有弹簧预设定义为无大小写枚举的运动令牌spring-smooth-default— 对所有 UI 过渡默认使用 .smooth 弹簧spring-snappy-responsive— 对响应式交互使用 .snappy 弹簧spring-bouncy-celebration— 对玩味和庆祝时刻使用 .bouncy 弹簧spring-custom-parameters— 使用 response 和 dampingFraction 调整自定义弹簧spring-velocity-preservation— 弹簧在中断时保持速度spring-never-linear— 切勿对交互式 UI 使用线性或 easeInOutspring-completion-chaining— 使用 withAnimation 完成链式序列
2. 时间与感觉 (关键)
feel-250ms-max— 保持 UI 动画在 250ms 以下feel-faster-better— 更快的动画几乎总是感觉更好feel-asymmetric-enter-exit— 对进入和退出使用不对称时间feel-distance-proportional— 匹配持续时间与行进距离feel-haptic-sync— 将触觉反馈同步到视觉动画关键帧feel-stagger-timing— 以 30-50ms 间隔交错显示
3. 手势连续性 (高)
gesture-rubber-band— 在拖动边界处使用橡皮筋效果gesture-momentum-dismiss— 基于速度或距离阈值解散gesture-snap-points— 使用速度感知的吸附点gesture-interruptible— 使所有手势动画可中断gesture-scroll-drag-conflict— 解决滚动和拖动手势冲突gesture-state-transient— 使用 GestureState 处理瞬时拖拽状态gesture-projected-landing— 预测手势速度以获得自然着陆位置
4. 空间过渡 (高)
spatial-matched-geometry— 对展开/折叠变形使用 matchedGeometryEffectspatial-zoom-navigation— 对集合详情使用缩放导航过渡 (iOS 18)spatial-transition-origin— 将过渡锚定到触发位置spatial-hero-shared-element— 共享多个元素 ID 以丰富英雄动画spatial-sheet-morph— 对工作表演示使用 matchedGeometryEffectspatial-tab-continuity— 在选项卡过渡中保持空间方向
5. 微交互 (高)
micro-button-press-scale— 在按压时将按钮缩放至 0.97 以获得触觉反馈micro-haptic-pairing— 将每个视觉状态更改与触觉反馈配对micro-symbol-effect— 对 SF Symbol 动画使用 symbolEffectmicro-toggle-bounce— 为切换状态更改添加弹跳micro-long-press-fill— 为长按操作动画渐进填充micro-loading-phase— 使用重复弹簧获得有机加载状态
6. 编排 (高)
orch-phase-animator— 对多步骤序列使用 PhaseAnimatororch-keyframe-animator— 对时间轴精确运动使用 KeyframeAnimatororch-stagger-children— 对编排的显示交错子元素orch-coordinated-entrance— 使用共享触发器协调多元素进入orch-timeline-view— 对连续重复动画使用 TimelineView
7. 工艺与打磨 (高)
craft-reduce-motion— 尊重 accessibilityReduceMotion 使用淡入淡出回退craft-blur-bridge— 使用模糊桥接不完美的过渡状态craft-drawing-group— 对 Metal 支持的复杂动画使用 drawingGroup()craft-geometry-group— 使用 geometryGroup() 隔离布局动画传播craft-transaction-debug— 使用 Transaction 调试和覆盖动画行为
8. 内容运动 (中高)
content-numeric-text— 对数字更改使用 contentTransition(.numericText)content-scroll-transition— 对滚动位置效果使用 scrollTransitioncontent-visual-effect— 对位置感知动画使用 visualEffectcontent-symbol-replace— 使用 contentTransition 动画符号替换content-text-renderer— 使用 Text Renderer 进行字符级动画 (iOS 18)
如何使用
阅读单独的参考文件以获取详细解释,包含不正确/正确的代码示例:
参考文件
| 文件 | 描述 | | references/_sections.md | 类别定义和排序 | | assets/templates/_template.md | 新规则模板 | | metadata.json | 版本和参考信息 |