Custom AnimatableModifier and Animatable
Animating custom drawn content by conforming to Animatable and AnimatableModifier.
Custom AnimatableModifier and Animatable is a free Swift Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The Animatable Protocol
Animatable tells SwiftUI how to interpolate a type during animation. Shapes conform to it automatically.
struct Wave: Shape, Animatable {
var amplitude: Double
var animatableData: Double {
get { amplitude }
set { amplitude = newValue }
}
func path(in rect: CGRect) -> Path { Path() }
}animatableData Property
SwiftUI reads and writes animatableData at each animation frame to interpolate between start and end values.
struct GrowingCircle: Shape {
var radius: Double
var animatableData: Double {
get { radius }
set { radius = newValue }
}
func path(in rect: CGRect) -> Path {
Path(ellipseIn: CGRect(x: rect.midX-radius, y: rect.midY-radius, width: radius*2, height: radius*2))
}
}AnimatablePair for Multiple Values
Use AnimatablePair to animate two independent values simultaneously.
struct Sector: Shape {
var startAngle: Double, endAngle: Double
var animatableData: AnimatablePair<Double, Double> {
get { AnimatablePair(startAngle, endAngle) }
set { startAngle = newValue.first; endAngle = newValue.second }
}
func path(in rect: CGRect) -> Path { Path() }
}ViewModifier + Animatable
Conforming a ViewModifier to Animatable lets you animate arbitrary visual effects.
struct Shake: ViewModifier, Animatable {
var animatableData: Double = 0
func body(content: Content) -> some View {
content.offset(x: sin(animatableData * .pi * 4) * 8)
}
}Driving the Animation
Change the animatable value inside withAnimation and SwiftUI interpolates via animatableData.
struct ShakeView: View {
@State private var shakes = 0.0
var body: some View {
Text("Hello")
.modifier(Shake(animatableData: shakes))
.onTapGesture {
withAnimation(.linear(duration: 0.5)) { shakes += 1 }
}
}
}AnimatableModifier (deprecated) vs Animatable + ViewModifier
AnimatableModifier is deprecated in later SDKs. Prefer conforming your ViewModifier to Animatable directly.
// Modern approach:
struct MyMod: ViewModifier, Animatable { ... }
// Avoid (deprecated):
// struct MyMod: AnimatableModifier { ... }Custom Number Types as animatableData
Any VectorArithmetic conforming type can be animatableData. Swift's CGFloat, Double, and AnimatablePair all qualify.
extension MyColor: VectorArithmetic {
static func += (lhs: inout MyColor, rhs: MyColor) { ... }
mutating func scale(by rhs: Double) { ... }
var magnitudeSquared: Double { ... }
}Progress-Based Modifier
A common pattern: animate a progress value from 0 to 1 and compute visual properties inside the modifier.
struct FillModifier: ViewModifier, Animatable {
var progress: Double
var animatableData: Double { get { progress } set { progress = newValue } }
func body(content: Content) -> some View {
content.overlay(Color.blue.opacity(progress))
}
}Chaining with .animation
Attach an animation to drive the animatable modifier's progress value automatically on state changes.
Text("Loading")
.modifier(FillModifier(progress: isLoaded ? 1 : 0))
.animation(.easeInOut(duration: 1.0), value: isLoaded)Animating Custom Shapes
The most powerful use: morphing between two path shapes by interpolating control points via animatableData.
struct Blob: Shape, Animatable {
var bulge: Double
var animatableData: Double { get { bulge } set { bulge = newValue } }
func path(in rect: CGRect) -> Path {
// compute bezier with bulge-adjusted control points
Path()
}
}Performance
SwiftUI calls the modifier body on every animation frame. Keep computation inside body minimal for smooth 60/120 fps.
// OK: simple math in body
// AVOID: network calls, heavy computation in animated bodyQuick Check
What does SwiftUI read and write on every animation frame to interpolate a custom animatable type?
Lesson Recap
Conform shapes or view modifiers to Animatable and expose animatableData (a VectorArithmetic value). SwiftUI interpolates it each frame. Use AnimatablePair for two values. Drive with withAnimation or .animation.
Frequently asked questions
Is the “Custom AnimatableModifier and Animatable” lesson free?
Yes — the full text of “Custom AnimatableModifier and Animatable” is free to read here on the web, and the Swift Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Swift Academy course, upgrade to CoddyKit PRO.
What will I learn in “Custom AnimatableModifier and Animatable”?
Animating custom drawn content by conforming to Animatable and AnimatableModifier. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Swift Academy?
No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Custom AnimatableModifier and Animatable” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Swift Academy lesson?
Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Implicit vs Explicit Animations
- matchedGeometryEffect for Hero Transitions
- Custom AnimatableModifier and Animatable
- TimelineView and Canvas for High-Performance Drawing