iOS Animation Graphics Skill
Skill18 starsChanged 58 days agoMITView on GitHub
Design, implement, debug, and review accessible Apple-platform animation and graphics with SwiftUI animation, Canvas, TimelineView, matched geometry, phase/keyframe animators, Core Animation, and Lottie. Use for motion design, custom drawing, transitions, particles, animated symbols, UIKit/AppKit bridging, Reduce Motion, and animation performance. Prefer native SwiftUI for app UI; use Core Animation or Lottie only when their capabilities are needed. Do not use this skill for SpriteKit/Metal game engines, video rendering, or image editing unless animation integration is the specific task.
In this repository14 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- app-intents-widgetsSkill
- Cross-Platform App Development SkillSkill
- iOS Accessibility SkillSkill
- iphone-duo-designSkill
- Memory Leak Diagnosis SkillSkill
- swift-concurrency-migrationSkill
- swiftdata-core-data-migrationsSkill
- Swift Modern Architecture SkillSkill
- Swift Performance Optimization SkillSkill
- SpeechAnalyzer Framework ExpertSkill
- SwiftUI Programming SkillSkill
- Swift Unit Testing SkillSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
18 rules. About 0 are common, 10 are distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈10
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 34
Do not drive a Canvas by changing a captured scalar with withAnimation.
- Distinctive: line 39
Check the project’s deployment targets and third-party dependency version.
- Distinctive: line 42
Keep animation state as the source of truth.
- Distinctive: line 43
Test interruption, repeated taps, navigation, background/foreground, resizing, and device rotation.
- Very specific: line 49
Use withAnimation for an explicit state mutation.
- Distinctive: line 50
Prefer opacity, scale, rotation, and offset for hot paths.
- Distinctive: line 51
Keep stable identity across transitions.
- Distinctive: line 53
Use animation completion APIs only at their documented availability.
- Very specific: line 74
Read examples/example_canvas_waveform.swift for a complete iOS 15+ waveform.
- Distinctive: line 80
Avoid allocating images, formatters, or large collections inside the renderer.
- Very specific: line 87
Read examples/example_gradient_border.swift for a layout-safe, Reduce-Motion-aware border.
- Very specific: line 91
Use Lottie’s native SwiftUI LottieView on Lottie 4.3+.
- Very specific: line 93
Keep playback declarative with LottiePlaybackMode.
- Very specific: line 95
Read examples/example_lottie_animation.swift after adding a compatible Lottie package.
- Very specific: line 99
Read accessibilityReduceMotion in every view that autoplays, loops, travels, parallax-scrolls, or emits particles.
- Distinctive: line 101
Avoid rapid flashing and large involuntary motion.
- Distinctive: line 102
Do not make animation the only signal.
- Distinctive: line 103
Keep controls operable while animation is interrupted or disabled.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Apple UI Animation and Graphics
Choose the simplest rendering system that expresses the motion, then make accessibility and lifecycle behavior part of the design rather than a later patch.
Compatibility baseline
CanvasandTimelineViewrequire iOS 15, macOS 12, tvOS 15, or watchOS 8.matchedGeometryEffectrequires iOS 14 / macOS 11.PhaseAnimator,KeyframeAnimator, and the first symbol-effect APIs require iOS 17 / macOS 14.- Zoom navigation transitions and SwiftUI animation bridging into UIKit/AppKit require iOS 18 / macOS 15 where documented.
- Lottie’s native SwiftUI
LottieViewwas introduced in Lottie 4.3. Pin a tested package version and obey that release’s Xcode, Swift, and deployment requirements; Lottie 4.6 requires Xcode 16 / Swift 6. - Gate newer APIs with
#availableand provide a meaningful lower-target result. Treat 27-cycle APIs as unavailable unless the project actually builds with that SDK.
State the exact minimum that the proposed implementation needs; do not assign one minimum to every animation technique.
Select the rendering path
| Need | Preferred tool |
| Animate SwiftUI state, layout, or transitions | withAnimation, value-scoped .animation, transition |
| Several discrete or timed phases | PhaseAnimator / KeyframeAnimator on iOS 17+ |
| Draw many lightweight vector elements | Canvas |
| Redraw continuously from elapsed time | TimelineView(.animation) around Canvas |
| Synchronize two SwiftUI layouts | matchedGeometryEffect |
| Animate an SF Symbol | symbolEffect where available |
| Control a layer tree or UIKit view | Core Animation / UIViewRepresentable |
Play designer-authored JSON or .lottie assets | Lottie |
Do not drive a Canvas by changing a captured scalar with withAnimation; a renderer closure is not itself animatable data. Derive each frame from a TimelineView date or expose explicit animatable values in a custom view.
Workflow
- Declare the before/after states and what event starts or stops motion.
- Check the project’s deployment targets and third-party dependency version.
- Define Reduce Motion behavior: static end state, dissolve, shortened travel, or no autoplay.
- Pick the rendering path from the table above.
- Keep animation state as the source of truth; avoid imperative controls that drift from SwiftUI state.
- Test interruption, repeated taps, navigation, background/foreground, resizing, and device rotation.
- Profile representative hardware with SwiftUI, Core Animation, and Time Profiler instruments when frames drop.
SwiftUI rules
- Scope implicit animations with
.animation(_:value:). - Use
withAnimationfor an explicit state mutation. - Prefer opacity, scale, rotation, and offset for hot paths; animating frame constraints can trigger repeated layout.
- Keep stable identity across transitions. Do not use changing random IDs to force animation.
- Let interactive gestures update state continuously and choose a spring only when the gesture ends.
- Use animation completion APIs only at their documented availability; do not infer completion from a fixed sleep.
@Environment(\.accessibilityReduceMotion) private var reduceMotion
@State private var isExpanded = false
Button("Details") {
withAnimation(reduceMotion ? nil : .snappy) {
isExpanded.toggle()
}
}
.scaleEffect(isExpanded ? 1.08 : 1)
.opacity(isExpanded ? 1 : 0.85)For multi-stage motion on iOS 17+, prefer phase or keyframe animators over chains of delayed tasks. Provide a simple state change for earlier targets.
Canvas and continuous drawing
Canvas redraws when its surrounding view invalidates. For time-based graphics, wrap it in TimelineView(.animation(paused:)) and derive phase from context.date. Pause the schedule for Reduce Motion and when the animation is not visible or active.
Read examples/example_canvas_waveform.swift for a complete iOS 15+ waveform. It uses time as the source of truth, has no accumulating phase drift, and renders a static frame for Reduce Motion.
Control work per frame:
- Step vector paths at the coarsest visually acceptable interval.
- Cache expensive geometry or resolved symbols when inputs are unchanged.
- Avoid allocating images, formatters, or large collections inside the renderer.
- Respect
TimelineViewcadence and pause offscreen work.
Core Animation bridging
Layer geometry is invalid in makeUIView when the host view still has zero bounds. Put layer sizing and mask paths in a UIView subclass’s layoutSubviews; disable implicit actions for those layout updates. Make playback updates idempotent and never force-unwrap a stored animation.
Read examples/example_gradient_border.swift for a layout-safe, Reduce-Motion-aware border. Use the same pattern for emitter layers: update frame and emitterPosition from current bounds, set birthRate to zero when paused/reduced/offscreen, and remove animations during teardown.
Lottie
Use Lottie’s native SwiftUI LottieView on Lottie 4.3+; do not create local types named LottieView or LottieAnimationView. Those names collide with library types and can make state declarations recursively refer to the wrong type.
Keep playback declarative with LottiePlaybackMode. For Reduce Motion, show a meaningful static progress frame or an asset-authored reduced-motion marker rather than autoplaying. Verify the animation asset exists in the intended bundle and test VoiceOver focus while it plays.
Read examples/example_lottie_animation.swift after adding a compatible Lottie package. The example intentionally has an external dependency and is not part of dependency-free compiler validation.
Accessibility
- Read
accessibilityReduceMotionin every view that autoplays, loops, travels, parallax-scrolls, or emits particles. - Preserve meaning when motion is removed; do not simply hide success/error state.
- Avoid rapid flashing and large involuntary motion.
- Do not make animation the only signal. Pair it with text, shape, sound, or haptics as appropriate.
- Keep controls operable while animation is interrupted or disabled.
- Decorative drawing should be accessibility-hidden; meaningful charts need labels or an accessible representation.
Performance and correctness review
- Does the animation have one authoritative state and a deterministic stop condition?
- Does continuous work stop offscreen, in the background, and under Reduce Motion?
- Are Core Animation layer frames recalculated after nonzero layout and rotation?
- Are repeated SwiftUI updates idempotent rather than restarting the same CA animation?
- Does a Lottie view use the package’s types without name shadowing?
- Are availability and package-version requirements explicit?
- Has the effect been tested on a physical low-end supported device?
- Are render cost, layout passes, overdraw, and memory measured rather than guessed?
Supporting material
- README.md summarizes minimums and resource selection.
- examples/example_canvas_waveform.swift demonstrates scheduled Canvas redraw.
- examples/example_gradient_border.swift demonstrates layout-safe Core Animation bridging.
- examples/example_lottie_animation.swift demonstrates non-shadowing declarative Lottie playback.
- examples/prompts.md contains representative activation prompts.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

