AILW: Adding a Touch of Liveliness

watchOS series

I have been working on putting the finishing touches on the WatchKit app for Pedometer++. The watch app (like its iPhone counterpart) is a simple goal-based dashboard for your daily step counts as measured by the M7/8 motion chip. Once I finished the basic functionality I ended up with this:

It works, does the job, but ultimately felt rather flat. Especially for an app that you will likely only spend a moment checking. It just didn’t seem like a particularly engaging experience.

The answer to improving that turned out to be adding a touch of liveliness into the opening experience. WatchKit doesn’t have the capability to do the typical animations that we’ve grown used to on iOS. We are spoiled there with CoreAnimation and how easily I can just say “animate this view from here to there.”

On the Watch all animation must be done with pre-rendered images. In much the same way as a cell animator would draw a moving character, we must generate an image for each frame of our animation. They are then displayed in sequence by the Watch to provide the desired effect.

After a bit of work I ended up with this:

The result feels more engaging and appealing visually. The whole thing isn’t long (just 0.5 seconds) but makes the experience of opening the app significantly less jarring. That subtle change though makes a big difference. I doubt many users would be able to articulate the difference but I’m sure they’d feel it.

I suspect these little touches will go a long way in differentiating a WatchKit app. Since doing anything lively takes significant effort the apps that go that extra mile will likely stand out.

How that works

I don’t have a lot of experience with doing this kind of manual animation so it took a lot of trial and error to find the right approach.

Before I explain exactly how I ended up doing it, here is the same animation slowed down and with a white background. This makes it much easier to see what is going on.

Each bar on the graph is represented by an image of a single color. To achieve the appearance of them growing I needed for that color to slowly fill up the bar from the bottom.

I used a great project called FlipBook1 by James Frost to do the actual rendering. This project provides a straightforward mechanism for recording the individual frames of a CoreAnimation based animation. You setup a normal UIView to animate however you’d like and then have FlipBook render and save as PNG each individual frame.

Once I had generated the required images (237 in all) I then needed to make the non colored portions of the images transparent. That way they can get blended with the background group. I did this by using ImageMagick to replace black with transparency2.

for i in *.png ; do convert "$i" -transparent black "${i}" ; done

From there it was just a question of coordinating the animation to occur when the data for the display is loaded.

  1. Somewhat amusingly this is the first Swift I’ve ever written. 

  2. To come up with this command I still reference this tweet, probably the most useful 140 characters I’ve ever seen on Twitter. 

David Smith