IO

iOS Animation Graphics Skill

A tool for implementing engaging motion and visual effects in iOS applications.

Install

mkdir -p .claude/skills/ios-animation-graphics-skill && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/10250" && unzip -o skill.zip -d .claude/skills/ios-animation-graphics-skill && rm skill.zip

Installs to .claude/skills/ios-animation-graphics-skill

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Creating animations and graphics using SwiftUI Canvas, Core Animation, and Lottie integration for engaging iOS app experiences.
127 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Create SwiftUI animations
  • Implement Lottie integrations
  • Draw custom graphics with Canvas
  • Apply hardware-accelerated transitions

How it works

It provides guidelines and code patterns for using native iOS frameworks to create performant, state-driven animations and custom graphics.

Inputs & outputs

You give it
Animation or graphics requirement
You get back
SwiftUI animation code

When to use iOS Animation Graphics Skill

  • Create ios animations
  • Implement lottie integration
  • Draw custom graphics with canvas

About this skill

iOS Animation Graphics Skill

This skill provides expertise in creating smooth animations and custom graphics for iOS applications using SwiftUI Canvas, Core Animation, and Lottie. It covers animation principles, performance considerations, and integration with Apple's design system.

Best Practices

  1. Performance First: Use lightweight animations that don't impact scrolling or user interaction.

  2. Meaningful Motion: Ensure animations enhance user experience and provide visual feedback.

  3. Consistent Timing: Use standard animation durations (0.2-0.5 seconds) for familiarity.

  4. Hardware Acceleration: Leverage GPU-accelerated properties for smooth animations.

  5. Accessibility: Respect reduced motion preferences and provide alternatives.

  6. State-Driven: Bind animations to view state for automatic updates.

Animation Guidelines

  • Use SwiftUI's built-in animation modifiers for simple transitions.
  • Implement Canvas for custom drawings and complex graphics.
  • Integrate Lottie for designer-created animations.
  • Combine multiple animation techniques for rich interactions.
  • Test animations on actual devices for performance.
  • Consider different screen sizes and orientations.

Examples

Example 1: Basic SwiftUI Animations

User Prompt: "Create a button that scales and changes color when tapped using SwiftUI animations."

Expected Output:

import SwiftUI

struct AnimatedButton: View {
    @State private var isPressed = false
    @State private var tapCount = 0
    
    var body: some View {
        ZStack {
            Circle()
                .fill(isPressed ? Color.blue : Color.red)
                .frame(width: isPressed ? 120 : 100, height: isPressed ? 120 : 100)
                .shadow(radius: isPressed ? 10 : 5)
                .animation(.spring(response: 0.3, dampingFraction: 0.6), value: isPressed)
            
            Text("\(tapCount)")
                .font(.title)
                .foregroundColor(.white)
                .scaleEffect(isPressed ? 1.2 : 1.0)
                .animation(.easeInOut(duration: 0.2), value: isPressed)
        }
        .onTapGesture {
            isPressed.toggle()
            tapCount += 1
            
            // Reset after animation
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                isPressed = false
            }
        }
    }
}

// Advanced example with multiple animations
struct ComplexAnimatedView: View {
    @State private var isAnimating = false
    
    var body: some View {
        VStack(spacing: 20) {
            RoundedRectangle(cornerRadius: 20)
                .fill(Color.blue)
                .frame(width: isAnimating ? 200 : 100, height: 100)
                .rotationEffect(.degrees(isAnimating ? 360 : 0))
                .offset(y: isAnimating ? -50 : 0)
                .animation(.interpolatingSpring(mass: 1.0, stiffness: 100, damping: 10, initialVelocity: 0), value: isAnimating)
            
            Button("Animate") {
                isAnimating.toggle()
            }
            .buttonStyle(.borderedProminent)
        }
        .padding()
    }
}

Example 2: SwiftUI Canvas for Custom Graphics

User Prompt: "Draw a custom animated waveform using SwiftUI Canvas."

Expected Output:

import SwiftUI

struct WaveformView: View {
    @State private var phase = 0.0
    
    var body: some View {
        VStack {
            Canvas { context, size in
                let width = size.width
                let height = size.height
                let centerY = height / 2
                
                // Draw waveform
                var path = Path()
                path.move(to: CGPoint(x: 0, y: centerY))
                
                for x in stride(from: 0, to: width, by: 1) {
                    let relativeX = x / width
                    let y = centerY + sin(relativeX * .pi * 4 + phase) * 30
                    path.addLine(to: CGPoint(x: x, y: y))
                }
                
                context.stroke(path, with: .color(.blue), lineWidth: 2)
                
                // Draw amplitude bars
                for i in 0..<10 {
                    let barHeight = abs(sin(phase + Double(i) * 0.5)) * 50
                    let barX = width * 0.1 * Double(i + 1)
                    
                    let barRect = CGRect(x: barX - 2, y: centerY - barHeight/2, width: 4, height: barHeight)
                    context.fill(Path(barRect), with: .color(.green.opacity(0.6)))
                }
            }
            .frame(height: 200)
            .background(Color.gray.opacity(0.1))
            .cornerRadius(10)
            
            Button("Animate Wave") {
                withAnimation(.linear(duration: 2).repeatForever(autoreverses: false)) {
                    phase += .pi * 2
                }
            }
            .buttonStyle(.bordered)
        }
        .padding()
    }
}

// Interactive canvas example
struct DrawingCanvas: View {
    @State private var paths: [Path] = []
    @State private var currentPath = Path()
    @State private var isDrawing = false
    
    var body: some View {
        VStack {
            Canvas { context, size in
                for path in paths {
                    context.stroke(path, with: .color(.blue), lineWidth: 3)
                }
                context.stroke(currentPath, with: .color(.red), lineWidth: 3)
            }
            .frame(height: 300)
            .background(Color.white)
            .border(Color.gray, width: 1)
            .gesture(
                DragGesture(minimumDistance: 0)
                    .onChanged { value in
                        let point = value.location
                        if !isDrawing {
                            currentPath.move(to: point)
                            isDrawing = true
                        } else {
                            currentPath.addLine(to: point)
                        }
                    }
                    .onEnded { _ in
                        paths.append(currentPath)
                        currentPath = Path()
                        isDrawing = false
                    }
            )
            
            Button("Clear") {
                paths = []
                currentPath = Path()
            }
            .buttonStyle(.bordered)
        }
        .padding()
    }
}

Example 3: Lottie Animation Integration

User Prompt: "Integrate a Lottie animation that plays on button tap."

Expected Output: First, add Lottie to your project using Swift Package Manager:

import SwiftUI
import Lottie

struct LottieAnimationView: View {
    @State private var isPlaying = false
    @State private var animationView: LottieAnimationView?
    
    var body: some View {
        VStack(spacing: 20) {
            // Lottie Animation Container
            ZStack {
                Color.gray.opacity(0.1)
                    .frame(height: 200)
                    .cornerRadius(10)
                
                if let animationView = animationView {
                    LottieView(animationView: animationView)
                        .frame(height: 200)
                } else {
                    Text("Loading animation...")
                        .foregroundColor(.secondary)
                }
            }
            
            HStack(spacing: 20) {
                Button(action: {
                    playAnimation()
                }) {
                    Label("Play", systemImage: "play.fill")
                }
                .buttonStyle(.borderedProminent)
                .disabled(isPlaying)
                
                Button(action: {
                    stopAnimation()
                }) {
                    Label("Stop", systemImage: "stop.fill")
                }
                .buttonStyle(.bordered)
                .disabled(!isPlaying)
            }
        }
        .padding()
        .onAppear {
            loadAnimation()
        }
    }
    
    private func loadAnimation() {
        // Load animation from bundle (you would add the JSON file to your project)
        if let animation = LottieAnimation.named("celebration") {
            animationView = LottieAnimationView(animation: animation)
            animationView?.loopMode = .playOnce
        }
    }
    
    private func playAnimation() {
        isPlaying = true
        animationView?.play { _ in
            isPlaying = false
        }
    }
    
    private func stopAnimation() {
        animationView?.stop()
        isPlaying = false
    }
}

// UIViewRepresentable wrapper for Lottie
struct LottieView: UIViewRepresentable {
    let animationView: LottieAnimationView
    
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        view.addSubview(animationView)
        animationView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            animationView.topAnchor.constraint(equalTo: view.topAnchor),
            animationView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            animationView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            animationView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ])
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
        // Update if needed
    }
}

// Alternative: Using Lottie with SwiftUI state
struct StatefulLottieView: View {
    @State private var play = false
    
    var body: some View {
        VStack {
            LottieView(animation: .named("loading"))
                .playbackMode(.playing(.toProgress(1, loopMode: .loop)))
                .frame(height: 100)
            
            Button("Toggle Animation") {
                play.toggle()
            }
            .buttonStyle(.bordered)
        }
    }
}

Example 4: Cor


Content truncated.

When not to use it

  • Non-iOS platform graphics
  • Complex game engine development

Prerequisites

SwiftUICore AnimationLottie

Limitations

  • Requires actual device testing for performance
  • Limited to iOS frameworks

How it compares

It emphasizes performance and accessibility standards specific to Apple's design system rather than generic animation libraries.

Compared to similar skills

iOS Animation Graphics Skill side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
iOS Animation Graphics Skill (this skill)05moNo flagsIntermediate
mobile-design1494moReviewIntermediate
mobile-games116moNo flagsIntermediate
mobile-ios-design2725moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry