iOS Animation Code Review
Quick Reference
references/performance.md |
| Reduce Motion, VoiceOver, motion sensitivity |
references/accessibility.md |
| Transition protocol, matchedGeometryEffect, navigation transitions |
references/transitions.md |
Output Format
Report each finding as:
CODEBLOCK0
Example: INLINECODE0
All details, code suggestions, and rationale follow after the header line.
Review Checklist
- - [ ]
@Environment(\.accessibilityReduceMotion) checked — animations have Reduce Motion fallback - [ ] Animation is not the sole feedback channel — important state changes pair with haptics (
.sensoryFeedback) or audio - [ ] Custom animation isn't duplicating system-provided motion (standard nav transitions, sheet presentation, SF Symbol effects)
- [ ] Animations on frequent interactions are brief and unobtrusive — or absent (system handles it)
- [ ] All animations are interruptible — user is never forced to wait for completion before interacting
- [ ] Spring animations use
duration/bounce parameters (not raw mass/stiffness/damping unless UIKit/CA) - [ ] No deprecated
.animation() without value: parameter - [ ]
withAnimation wraps state changes, not view declarations - [ ]
matchedGeometryEffect IDs are stable and unique within the namespace - [ ]
geometryGroup() used when parent geometry animates with child views appearing - [ ] Looping animations (
PhaseAnimator, symbolEffect) have finite phases or appropriate trigger - [ ] No
CATransaction.setAnimationDuration() in UIView-backed layers (use UIView.animate instead) - [ ] Interactive animations handle interruption (re-trigger mid-flight doesn't break state)
- [ ] Shadow animations provide explicit
shadowPath (avoids per-frame recalculation) - [ ] Gesture-driven animations preserve velocity on release for natural completion
- [ ] Gesture-driven feedback follows spatial expectations (dismiss direction matches reveal direction)
- [ ] No animation of
.id() modifier (destroys view identity — use transition or matchedGeometryEffect instead)
When to Load References
- - Incorrect spring setup or
withAnimation scope issues → swiftui-animation-patterns.md - Hitches, dropped frames, or expensive animations in scroll views → performance.md
- Missing Reduce Motion handling or motion accessibility → accessibility.md
- INLINECODE18 glitches or custom
Transition bugs → transitions.md
Review Questions
- 1. Does every animation have a Reduce Motion fallback that preserves the information conveyed? Is animation the only feedback channel, or are haptics/audio supplementing it?
- Is this custom animation necessary, or does the system already provide it (standard transitions, SF Symbol effects, Liquid Glass)?
- Could this animation cause frame drops — is it animating expensive properties (blur, shadow without path, mask) in a list or scroll view?
- Are all animations interruptible? Can the user act without waiting for completion? Does gesture-driven feedback follow spatial expectations?
- Is
withAnimation scoped to the minimal state change needed, or is it wrapping unrelated mutations? - For
matchedGeometryEffect — are source and destination using the same ID and namespace, and is only one visible at a time?
iOS动画代码审查
快速参考
references/performance.md |
| 减少动态效果、旁白、运动敏感度 |
references/accessibility.md |
| 过渡协议、matchedGeometryEffect、导航过渡 |
references/transitions.md |
输出格式
按以下格式报告每个发现:
[文件:行号] 问题标题
示例:[AnimatedCard.swift:42] 弹簧动画缺少减少动态效果回退
所有详细信息、代码建议和理由均跟在标题行之后。
审查清单
- - [ ] 已检查@Environment(\.accessibilityReduceMotion) — 动画具有减少动态效果回退
- [ ] 动画不是唯一的反馈通道 — 重要状态变化配合触觉反馈(.sensoryFeedback)或音频
- [ ] 自定义动画未重复系统提供的动效(标准导航过渡、表单呈现、SF符号效果)
- [ ] 频繁交互上的动画简短且不显眼 — 或不存在(由系统处理)
- [ ] 所有动画均可中断 — 用户无需等待动画完成即可交互
- [ ] 弹簧动画使用duration/bounce参数(除非是UIKit/CA,否则不使用原始质量/刚度/阻尼)
- [ ] 没有使用不带value:参数的已弃用.animation()
- [ ] withAnimation包裹状态更改,而非视图声明
- [ ] matchedGeometryEffect的ID在命名空间内稳定且唯一
- [ ] 当父几何体与子视图一起动画时使用geometryGroup()
- [ ] 循环动画(PhaseAnimator、symbolEffect)具有有限阶段或适当触发器
- [ ] 不在UIView支持的图层中使用CATransaction.setAnimationDuration()(改用UIView.animate)
- [ ] 交互式动画处理中断(中途重新触发不会破坏状态)
- [ ] 阴影动画提供显式shadowPath(避免每帧重新计算)
- [ ] 手势驱动动画在释放时保留速度以实现自然完成
- [ ] 手势驱动反馈遵循空间预期(关闭方向与显示方向一致)
- [ ] 不对.id()修饰符进行动画(破坏视图标识 — 改用transition或matchedGeometryEffect)
何时加载参考文档
- - 弹簧设置不正确或withAnimation作用域问题 → swiftui-animation-patterns.md
- 卡顿、帧率下降或滚动视图中的昂贵动画 → performance.md
- 缺少减少动态效果处理或运动无障碍 → accessibility.md
- matchedGeometryEffect故障或自定义Transition错误 → transitions.md
审查问题
- 1. 每个动画是否都有保留所传达信息的减少动态效果回退?动画是否是唯一的反馈通道,还是有触觉/音频作为补充?
- 这个自定义动画是否必要,还是系统已经提供了(标准过渡、SF符号效果、Liquid Glass)?
- 这个动画是否会导致帧率下降 — 是否在列表或滚动视图中对昂贵属性(模糊、无路径的阴影、遮罩)进行动画?
- 所有动画是否都可中断?用户是否无需等待完成即可操作?手势驱动反馈是否遵循空间预期?
- withAnimation的作用域是否仅限于所需的最小状态更改,还是包裹了不相关的变更?
- 对于matchedGeometryEffect — 源和目标是否使用相同的ID和命名空间,且一次只有一个可见?