Select Page
Recently, I found myself in need of a progress circle that provided both percentage, and indeterminate display. I found one in the form of the M13ProgressSuite. While this library has a great selection of visual modes – I found a few bugs in its visual consistency.

I also didn’t like how the ring would jump when moving between the indeterminate and progress modes, I wanted it to smoothly transition between the two.

Here I’ll walk through how I rolled my own in a couple of hundred lines.

I’m not reading all that! Just give me the code.

I’ll implement the following features:

  1. indeterminate ‘spinner’ mode.
  2. progress mode where the circle arc represents a percentage, with an optional label showing the percentage as text.
  3. smooth arc transition between indeterminate and progress modes.
  4. visual ‘pulse’ when in progress mode, in case progress is very slow.
The basic spinner animation consists of 2 parts, a rotation animation, and the animation of the stroke to change the length of the arc back and forth.
There is a little trick to ensuring that your newly scheduled animation picks up smoothly from the previous one. The PresentationLayer property of CALayer holds the visual state of the layer, as produced after any animation transformations have been applied.
This way we can capture the rendered StrokeEnd, and use it to initialize the From value of the next animation.
To transition between the two states, we need to ease-out the rotation animation, and ease in/out the stroke animation, animating the stroke from the currently visible value, to the determinate ‘Progress Value’.

We do that with the following:

As you switch the control between Indeterminate true/false, it will transition smoothly between the visual representations of the two.

Grab the code from Github, and have a play!