CAAnimation issues manifest as missing completion handlers, wrong timing, or jank under specific conditions. Core principle 90% of CAAnimation problems are CATransaction timing, layer state, or frame rate assumptions, not Core Animation bugs.
Confirm successful installation by checking the skill directory location:
.cursor/skills/axiom-uikit-animation-debugging
Restart Cursor to activate axiom-uikit-animation-debugging. Access via /axiom-uikit-animation-debugging in your agent's command palette.
โ
Security Notice
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
CAAnimation issues manifest as missing completion handlers, wrong timing, or jank under specific conditions. Core principle 90% of CAAnimation problems are CATransaction timing, layer state, or frame rate assumptions, not Core Animation bugs.
Red Flags โ Suspect CAAnimation Issue
If you see ANY of these, suspect animation logic not device behavior:
Completion handler fires on simulator but not device
Animation duration (0.5s) doesn't match visual duration (1.2s)
Spring animation looks correct on iPhone 15 Pro but janky on older devices
Gesture + animation together causes stuttering (fine separately)
[weak self] in completion handler and you're not sure why
โ FORBIDDEN Hardcoding duration/values to "match what actually happens"
This ships device-specific bugs to users on different hardware
Do not rationalize this as a "temporary fix" or "good enough"
Critical distinction Simulator often hides timing issues (60Hz only, no throttling). Real devices expose them (variable frame rate, CPU throttling, background pressure). MANDATORY: Test on real device (oldest supported model) before shipping.
Mandatory First Steps
ALWAYS run these FIRST (before changing code):
// 1. Check if completion is firing at allanimation.completion ={[weakself] finished inprint("๐ฅ COMPLETION FIRED: finished=\(finished)")guardletself=selfelse{print("๐ฅ SELF WAS NIL")return}// original code}// 2. Check actual duration vs declaredlet startTime =Date()let anim =CABasicAnimation(keyPath:"position.x")anim.duration =0.5// Declaredlayer.add(anim, forKey:"test")DispatchQueue.main.asyncAfter(deadline:.now()+0.51){print("Elapsed: \(Date().timeIntervalSince(startTime))")// Actual}// 3. Check what animations are activeiflet keys = layer.animationKeys(){print("Active animations: \(keys)")for key in keys {iflet anim = layer.animation(forKey: key){print("\(key): duration=\(anim.duration), removed=\(anim.isRemovedOnCompletion)")}}}// 4. Check layer stateprint("Layer speed: \(layer.speed)")// != 1.0 means timing is scaledprint("Layer timeOffset: \(layer.timeOffset)")// != 0 means animation is offset
What this tells you
Completion print appears โ Handler fires, issue is in callback code
Completion print missing โ Handler not firing, check CATransaction/layer state
Elapsed time == declared โ Duration is correct, visual jank is from frames
Elapsed time != declared โ CATransaction wrapping is changing duration
layer.speed != 1.0 โ Something is slowing animation
Active animations list is long โ Multiple animations competing
MANDATORY INTERPRETATION
Before changing ANY code, you must identify which ONE diagnostic is the root cause:
If completion fires but elapsed time != declared duration โ Apply Pattern 2 (CATransaction)
If completion doesn't fire AND isRemovedOnCompletion is true โ Apply Pattern 3
If completion fires but visual is janky โ MUST profile with Instruments first
You cannot guess "it's probably frames" - prove it with data
Profile > Core Animation instrument shows frame drops with certainty
If you skip Instruments, you're guessing
If diagnostics are contradictory or unclear
STOP. Do NOT proceed to patterns yet
Add more print statements to narrow the cause
Ask: "The diagnostics show X and Y but Z doesn't match. What am I missing?"
Profile with Instruments > Core Animation if unsure
Decision Tree
CAAnimation problem?
โโ Completion handler never fires?
โ โโ On simulator only?
โ โ โโ Simulator timing is different (60Hz). Test on real device.
โ โโ On real device only?
โ โ โโ Check: isRemovedOnCompletion and fillMode
โ โ โโ Check: CATransaction wrapping
โ โ โโ Check: app goes to background during animation
โ โโ On both simulator and device?
โ โโ Check: completion handler is set BEFORE adding animation
โ โโ Check: [weak self] is actually captured (not nil before completion)
โ
โโ Duration mismatch (declared != visual)?
โ โโ Is layer.speed != 1.0?
โ โ โโ Something scaled animation duration. Find and fix.
โ โโ Is animation wrapped in CATransaction?
โ โ โโ CATransaction.setAnimationDuration() overrides animation.duration
โ โโ Is visual duration LONGER than declared?
โ โโ Simulator (60Hz) vs device frame rate (120Hz). Recalculate for real hardware.
โ
โโ Spring physics wrong on device?
โ โโ Are values hardcoded for one device?
โ โ โโ Use device performance class, not model
โ โโ Are damping/stiffness values swapped with mass/stiffness?
โ โ โโ Check CASpringAnimation parameter meanings
โ โโ Does it work on simulator but not device?
โ โโ Simulator uses 60Hz. Device may use 120Hz. Recalculate.
โ
โโ Gesture + animation jank?
โโ Are animations competing (same keyPath)?
โ โโ Remove old animation before adding new
โโ Is gesture updating layer while animation runs?
โ โโ Use CADisplayLink for synchronized updates
โโ Is gesture blocking the main thread?
โโ Profile with Instruments > Core Animation
Common Patterns
Pattern Selection Rules (MANDATORY)
Apply ONE pattern at a time, in this order
Always start with Pattern 1 (Completion Handler Basics)
If completion NEVER fires โ Pattern 1
Verify completion is set BEFORE add() with print statement (line 33)
Only proceed to Pattern 2 if completion FIRES but timing is wrong
Then Pattern 2 (CATransaction duration mismatch)
Only if completion fires but elapsed time != declared duration
Check logs from Mandatory First Steps (line 40-47)
Then Pattern 3 (isRemovedOnCompletion)
Only if animation completes but visual state reverts
Patterns 4-7 Apply based on specific symptom (see Decision Tree line 91+)
FORBIDDEN
โ Applying multiple patterns at once ("let me try Pattern 2 AND Pattern 4 together")
โ Skipping Pattern 1 because "I already know it's not that"
โ Combining patterns without understanding why each is needed
โ Trying patterns randomly and hoping one works
Pattern 1: Completion Handler Basics
โ WRONG (Handler set AFTER adding animation)
layer.add(animation, forKey:"myAnimation")animation.completion ={ finished in// โ Too late!print("Done")}
CATransaction.begin()CATransaction.setAnimationDuration(2.0)// โ Overrides all animations!let anim =CABasicAnimation(keyPath:"position")anim.duration =0.5// This is ignoredlayer.add(anim, forKey:nil)CATransaction.commit()// Animation takes 2.0 seconds, not 0.5
โ CORRECT (Set duration on animation, not transaction)
let anim =CABasicAnimation(keyPath:"position")anim.duration =0.5layer.add(anim, forKey:nil)// No CATransaction wrapping
Why CATransaction.setAnimationDuration() affects ALL animations in the transaction block. Use it only if you want to change all animations uniformly.
Pattern 3: isRemovedOnCompletion & fillMode
โ WRONG (Animation disappears after completion)
let anim =CABasicAnimation(keyPath:"opacity")anim.fromValue =1.0anim.toValue =0.0anim.duration =0.5layer.add(anim, forKey:nil)
Implementation Guide
Prerequisites
โบClaude Desktop or compatible AI client with skill support
โบClear understanding of task or problem to solve
โบWillingness to iterate and refine outputs
Time Estimate
15-45 minutes depending on use case complexity
Steps
1Install skill using provided installation command
2Test with simple use case relevant to your work
3Evaluate output quality and relevance
4Iterate on prompts to improve results
5Integrate into regular workflow if valuable
Common Pitfalls
โ Expecting perfect results without iteration
โ Not providing enough context in prompts
โ Using skill for tasks outside its intended scope
โ Accepting outputs without review and validation
Best Practices
โ Do
+Start with clear, specific prompts
+Provide relevant context and constraints
+Review and refine all outputs before using
+Iterate to improve output quality
+Document successful prompt patterns
โ Don't
โDon't use without understanding skill limitations
โDon't skip validation of outputs
โDon't share sensitive information in prompts
โDon't expect skill to replace human judgment
๐ก Pro Tips
โ Be specific about desired format and style
โ Ask for multiple options to choose from
โ Request explanations to understand reasoning
โ Combine AI efficiency with human expertise
When to Use This
โ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
โ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
Learning Path
1Familiarize yourself with skill capabilities and limitations
2Start with low-risk, non-critical tasks
3Progress to more complex and valuable use cases
4Build expertise through regular use and experimentation