Creating a Dynamically Sized Progress Animation in Swift with Facebook Pop

Jaz Garewal

Last updated Jul 23, 2019

Before Spotify launched what it calls "Touch Preview,” we built this exact functionality for musx in their iPhone app. Like Spotify, anyone can tap and hold a song in musx and hear a preview. Our version, however, has the polish of an interactive graphic element to provide engaging visual feedback.

Since this feature uses Facebook's Pop framework, we thought the iOS developer community would find it useful to see how we created this UI touch effect. We put together an extensive video tutorial that steps through the details. To ensure we didn't reveal any of the proprietary elements of musx itself, we rewrote this feature in its own project and codebase. We even did it in Swift, just for fun.

For some backstory on the feature, musx wanted users to be able to quickly preview a song without committing to playing it. A tap and hold gesture was a natural choice. The first idea we implemented focused more on elapsed time itself. After the first round of iteration and testing, we discovered that users were less interested in the actual duration of the timer. We then decided to add a more visual cue.

As mentioned earlier, we worked with Facebook’s Pop for this feature. Pop is a framework that makes animating UIViews and CALayers more manageable. We also used UrbanApp’s UAProgressView, which simplifies the creation of circular progress views. During development, I learned more about CADisplayLink in particular for this feature. I’ll explain in the video what it is and how easy it makes animating an element over time.

One of the first items that we discussed when talking about implementing our final design was how to handle different finger sizes. Despite the size of the user's fingers, the animation should be able to be seen. We immediately felt that having a static size was not the best option but would work in a pinch. (That's a UIGestureRecognizer pun thrown in for free!)

After some experimenting, I found that we would basically sit in the middle between a static and dynamic implementation. As of iOS 8, developers have access to the diameter of a touch event, so using that could dynamically adjust the interaction based on the size of a user’s finger. Of course, if the app is running on iOS 7, we don't have access to majorRadius, so we provide a static value in that instance.

Want to learn more? Download musx to play with this feature, then watch the video tutorial. The tutorial uses Xcode 6.2 and Swift 1.1. We’ve marked the Swift 1.2 changes in the video.

Written By:

Jaz Garewal

Jaz is an app developer who enjoys creating tasteful interactions, fleets of world-dominating bots, and....puns.