This is fairly simple thing in iOS and you do not need to use any external library. I’ll use two
CABasicAnimation, so this is “cheap” way from the system resources point of view.
Start with empty project and in ViewController add three properties:
Here is two
CAShapeLayer properties which representing background (constant) shape of the indicator and progress shape.
percent variable will be needed for animations.
Now add progress and background shapes to the main view layer. Add the following code to the end of
It’s important to create shape layers once. This significantly simplifies code.
Now we need to draw background and progress shapes. Add new method
strokeWidth substracted from size to keep shape inside layer bounds. Also, keep in mind that it is much easier to position, rotate and scale
CALayer if its size and center are the same as for the shape.
Alternative way is to set
CALayer size to it’s view size and manually calculate center inside bounds.
backgroundShape can be defined in the following way:
Now we can draw
It’s the same shape but with different color. Only one difference is that it should indicate progress. There are several ways to do that and simplest is to define
strokeEnd variable that accept values from 0.0 to 1.0:
Final step is to make layer and shape responsible to view frame changes, because it would not happen automatically. In this example you need to override
viewWillLayoutSubviews() and add
updateIndicator() call. If you implement it as a separate UIView component then override
setNeedsLayout() and add this call:
If you made everything right then you will see the same image after app start:
What’s about animations?
It’s just six new lines of code that set values of CABasicAnimation. However, we need to modify updateIndicator().
You probably do not want to animate every progress change (for example, if you set initial value), so it’s good to have animation feature optional.
Now, add animation initialization to the beginning of
updateIndicator(...) method :
Here is initialization of
strokeEnd property key. Start value for animation is current value of
strokeEnd, end value is
percent, so animation will work for all cases. Timing function deserve separate topic for discussion, you may read more about these functions here.
Now we ready to apply animation to
progressShape layer. Add this code to the end of
Finally, change call in
viewWillLayoutSubviews() method to
That’s all! If you run the app then you see this:
Full code available at GitHub.
Here is how it looks like in Wasa+ app (Swedish AppStore only):