Recreating The Gear Icon Animation from iOS in SwiftUI
During a recent system update on my iPad, the system update animation caught my eye. The animation is an image of Settings app icon where the gears and cogs are spinning. I wanted to see if I could replicate the animation. Let’s see the result in SwiftUI.
To create the gear shape, I used Adobe Illustrator. First, I took a screenshot of the Settings app from iOS. I imported the image and set its size and position. Reducing the layer’s opacity allowed me to trace the gear shape. In a new layer, this outline can be replicated, giving us the cutout shape of the gear. I added an outline circle so the shape can be filled in.
To covert the shape created in Illustrator to a Bezier path that can be used in code, I used the app PaintCode. After resizing and positioning the imported shape in PaintCode, the Bezier path code can be copied and pasted into Xcode.
The spikes of the cog are created with a replicator layer. The replicator layer repeats the instance layer a specified number of times. The instance layer is filled with a simple shape that looks like a spike on the gear. With a rotation in proportion to the number of spikes, the replicator layer rotates each spike correctly.
In order to use CAReplicatorLayer
in SwiftUI, we must wrap our SpikeCircleView in a UIViewRepresentable View.
Our app icon view is simply a layered stack of views of different shapes and sizes. ZStack
is the perfect tool for the job, in addition to the RoundedRect and Circle shapes.
To make the gear spin, we use @State
along with rotation effects and animations. Direction can be changed by altering the order of the angle the rotation effect in relation to the @State
. Speed can be varied by changing the duration of the animations. When animated next to each other, the difference in direction will make it appear the different pieces are spinning at different speeds.
This is another example of the power of SwiftUI. SwiftUI enables me to create interesting and complex user interfaces simply and expressively.