Mastering SwiftUI Animations: Phase Animations
Explore the world of SwiftUI's phase-based animations in our latest post. Learn through custom examples and take your iOS animation skills up a notch!

Mazen Kourouche
Jun 12, 2023

With SwiftUI's recent advances, animation has become incredibly accessible for iOS developers. One of the latest additions is the phase-based animation, which is designed to animate discrete steps within an animation.
This article aims to explore phase-based animations, illustrating the process with custom examples. Let's dive in!
What is a Phase Animation?
Phase animations are SwiftUI's way of creating sequences of animations that cycle through predefined states or phases. With each phase representing a discrete step in an animation, you can create highly customisable animations with ease.
Using PhaseAnimator
SwiftUI's new PhaseAnimator is the hero of the show here. It enables developers to animate their content by cycling through a collection of phases. The basic structure of PhaseAnimator is as follows:
1PhaseAnimator(some Sequence<Phase>, content: (Phase) -> Content, animation: (Phase) -> Animation?)
In this block, you define a sequence of phases for the animation. Then, you use these phases within your content view builder closure to apply specific animations.
PhaseAnimator in Action
Let's illustrate phase animations with a simple example: a colour changing square, which becomes a circle as it animates.
First, let's create our Phase enum with each phase in our animation:
1enum Phase: CaseIterable {2 case initial3 case unroundCorners4 case rotate5 case finish6}
Next, let's we’ll add computed properties for each attribute we’ll be animating. For this animation, we’ll be animating the corner radius, colour and rotation:
1enum Phase: CaseIterable {2 case initial3 case unroundCorners4 case rotate5 case finish67 var cornerRadius: Double {8 switch self {9 case .initial, .finish: 5010 case .unroundCorners, .rotate: 011 }12 }1314 var rotation: Angle {15 switch self {16 case .initial, .unroundCorners: .degrees(0)17 case .rotate, .finish: .degrees(180)18 }19 }2021 var foregroundColor: Color {22 switch self {23 case .initial, .unroundCorners, .finish: .purple24 case .rotate: .blue25 }26 }27}
Corner radius: starts and finishes at 50 (half the width of our view - we’ll be setting it to 100) to create a circle, and 0 in between for our square.
Rotation: starts at 0, begins rotating after it morphs into a square, rotates, then rotates back after the animation ends.
Foreground colour: starts as purple, begins changing colour to blue after it morphs into a square, rotates, then changes back to purple.
Next, let's create our MorphShapeView. We’ll start with a basic rectangle.
1struct MorphShapeView: View {2 let size = 100.03 var body: some View {4 Rectangle()5 .frame(width: size, height: size)6 }7}
Now for the fun! We’ll use the PhaseAnimator with our MorphShapeView to create the animation:
1struct MorphShapeView: View {2 let size = 100.03 var body: some View {4 Rectangle()5 .frame(width: size, height: size)6 .phaseAnimator(7 Phase.allCases8 ) { content, phase in9 content10 /* Add modifiers based on phase */11 } animation: { phase in12 /* Modify animation based on phase */13 }14 }15}
To create the desired animation, we'll add modifiers and adjust the animation based on the phases. Here's the updated code:
1struct MorphShapeView: View {2 let size = 100.03 var body: some View {4 Rectangle()5 .frame(width: size, height: size)6 .phaseAnimator(7 Phase.allCases8 ) { content, phase in9 content10 .clipShape(RoundedRectangle(cornerRadius: phase.cornerRadius))11 .foregroundStyle(phase.foregroundColor)12 .rotationEffect(phase.rotation)13 } animation: { phase in14 switch phase {15 case .initial, .unroundCorners:16 return .spring(duration: 0.3)17 case .rotate: return .spring(duration: 1)18 case .finish:19 return .easeInOut(duration: 0.4)20 }21 }22 }23}
With these modifications, the MorphShapeView will smoothly transition through the defined phases, applying the appropriate modifiers and animations to achieve the desired effect.
Phase animations open a whole new world of opportunities for iOS developers using SwiftUI. With the new PhaseAnimator feature, the possibilities for highly customisable animations are endless. The key lies in understanding the flow and usage of this new tool.
Hopefully, this guide has shed some light on that, providing you with the confidence to create your phase animations in SwiftUI. Dive in, experiment, and have fun creating exciting and dynamic user interfaces!
In the next posts, we'll explore keyframe animations in SwiftUI and animating SF Symbols, taking your SwiftUI animations to the next level.