01Idea

I've been reading this book. For a while now. I’m listening to a podcast. A joke gets through and ricochets off the dark thoughts surrounding our recent move to Berlin. It's been a year. An image forms in my mind. It's an app icon with a skeleton on it. The skeleton is pointing up to its red notification badge. The number in the badge shows the number of weeks I have left to live. It's callous and self-pitying. But also layered, truthy and I bet I could make it in a week. I'm in: an app about weeks and how we spend them that takes one week to make.

02Sketch

My sketches could pass for a seven-year-old's (shout out to seven-year-olds) but nevertheless I find them necessary for starting something new. Surprising details come out of the idea-to-paper translation, otherwise there's probably not much there. Having a sketch in hand that embodies the original idea, no matter how rough, can serve as a valuable reference during the design process.

The initial sketch for the app. Not much to look at but the bones are there.
Crude but essential.

At this point the app was just the icon. Icon design is not my strong suit (see sketches) but this was arguably the most important aspect of the app. Mexican imagery immediately came to mind, Harry Smith’s ‘Heaven and Earth Magic’ too. After a few attempts on paper I’m convinced that I can work out a sufficient skeleton drawing in Sketch.

Harry Smith, the boss. Shout out to Google image search.
Influences: Harry Smith and the skulls of Sayulita.

03Mockup

Before I can put a number in the icon's badge, I'll need to get some information from the user: their current age and their age at death. I go with one question per screen and decide to use only standard iOS controls for speed and familiarity. I'm obsessed with black backgrounds (the true digital default) so I start there and begin adding type, then the button, then a control, then the different artboards. Working on the results screen leads to the arc shape.

First mockups: a workflow and a theme.

I go for a walk, come back and see that I've gone off the rails a bit: the UI needs to visually support the theme of the app. I get rid of the red accent color and focus on drawing a few skulls and bones inspired by grade school Q-tip skeletons. I use the modular approach taken with the bone shapes and apply it to the other screens. After that the concept and the interface begin to gel.

Take 2: black and white and bones all over. Working on the app icons and the info screen led me to the skeleton drawings. The skeleton drawings then spurred on a refinement of each of the screens.

With the visual elements in place, I took another look at the workflow. I realized that the first step "When were you born?" was overkill for the information I needed. Changing the question allowed me to get rid of the slider design and simplify it down to a single picker control.

Losing accuracy to reduce friction.

04Prototype

With the design in place, I moved on to fleshing it out in Framer. I made use of the new Design tab (Summer, 2017) to lay out the artboards, titles and buttons. I'm looking forward to when you can wire up events and add components without leaving the Design tab, it's that nice of a layout tool.

Framer design tab joy. Arc drawing via a custom module.
I spent the most time in Framer implementing a custom picker control. I regret nothing.

Once I had the controls and the results screen in good shape, I handed the prototype to the people around me. My 7-year-old was frightened by the concept but was still able to understand and complete all the steps without coaching. UX success, concept still questionable.

Prototype click through. Not a comfortable set of questions, but it's clear how to proceed.

05 Build

Prototype vetted, it's time to build the real thing in Xcode. Because I believe in the future and this is such a simple view hierarchy, I try to do as much as possible through storyboards. First step is to embed the default project’s storyboard in a navigation controller. From there I drag in some view controllers, one for each Framer artboard, then create a new swift subclass for each so that I can customize them later. I drag in the PDF assets, add the ‘Next’ buttons and set up the navigation by ‘control + dragging’ from the buttons to the view controllers.

I burned an hour at least on diddling with custom fonts in Xcode 9, look at those question marks. Always build to the device to check your work.

After figuring out how to style UIPicker, I then wrestled with getting my header labels right. Adding line breaks was having no effect. The solution ended up being setting the label’s line count property to 0 and then use ‘option + return’ to create the line breaks. Thank you Stack Overflow.

Now that the slider and the picker controls are sorted it's time to start the results screen. Borrowing from On the 8. I used CASpringAnimation to match the prototype's animation. In Framer it’s trivial to get callbacks for any property change on any object. Core Animation, not so much. I naively assumed that there would be a progress property on the CAAnimation that the view controller could observe. I ended up using a CALayer subclass that adds a callback to its draw in rect method. The solution was derived from these sources:

With that figured out, I then made the arc animations reflect the user input. Once I figured out the values for percentOfLifeLived and percentOfLifeLeft I started refining the spring animations and added timers to sequence the overlapping animations. I hope Interface Builder will support animation previews in the vein of IBDesignable someday: having to recompile to see every timing adjustment felt cumbersome.

CASpringAnimation updating a UILabel.

06 Add Love

The open source physics engine I used in Amos has since been baked into SpriteKit. Adding the skull and bone assets to the physics simulation required zero code as it was all laid out in the Scene Editor, that was a nice surprise. I then added touch handlers to the objects in the scene and mapped the x & y gravitation constants to the device’s accelerometer. This means that when the app is opened and the phone is held upright the skeleton body will fall to the floor.

Falling skeleton, bones moved with touch gestures.

Time to move on to the blinking skull animation. I have a go at a keyframe animation in After Effects. That's working well and I'm reminded of Lottie. I wrestled with getting Cocoapods set up: remember to open the workspace, not the project. Once I had that rolling, Bodymovin and Lottie were a breeze to work with.

After Effects -> Bodymovin -> Lottie -> Swift. Worth it.

After finishing the info screen I took stock of the app and decided that the current age screen needed some kind of skeleton motif as well. I wanted to drive the current age visualization from the picker view. I decided on a literal representation of age: one bone is added to the screen for every year you’ve been alive. The bones are created and destroyed when the picker changes and the direction of the picker's movement influences the forces at play.

It's raining bones again in existentialville.

At this point the results screen seemed to entirely too dull. A missed opportunity. I added a third ring that’s constantly spinning to represent the passing of time. I extracted this out into a RotatingArcClass and ended up using it three times.

Auto Layout getting a workout. The ring animation arc layers are being sized and positioned according to its containing view.

07 Shaders

The rings are nice but not enough. I wanted a full screen, 60fps visual effect for the results screen that spoke to what the information indicates. I quickly found Shadertoy and my way back to Spritekit beacuse of this post: Understanding Shaders in Spritekit. Here are the variables you'll need to convert to get a shader from ShaderToy working on iOS:

GlobalTime       u_time
iResolution      size
fragCoord.xy     gl_FragCoord.xy
fragColor        gl_FragColor
Warp speed ahead. Or so I thought.

No global vars, no in or out. It takes a bit of trial and error but the compiler messages helped quite a bit. After getting a flying-through-space-at-warpspeed effect to work I realized that it was the wrong visual. Not terrestrial or relatable enough. This screen should be grounded in a human perspective. I still like the infinity of the heavens motif as it implies something about the spirit. Thanks to this lovely example I ended up with an effect that reminded me of looking up at the night sky while in the mountains. There's more to do here, more serenity to add (like a dynamic moon that's in the correct phase or occasional birds passing by) but time was up for version 1. Here’s my final working shader:

void main()
{
    vec2  i      = gl_FragCoord.xy;
    float f      = .5;
    float r      = size.x;
    float t      = u_time * .03;
    float c      = cos( t );
    float s      = sin( t );
    i            = ( i / r - f ) * mat2( c, s, -s, c );
    vec3 d       = floor( f * r * vec3( i, f ) );
    gl_FragColor = vec4( 1. / ( f + exp( 2e2 * fract( sin( dot( d * sin( d.x ) + f, vec3( 13, 78.2, 57.1 ) ) ) * 1e5 ) ) ) );
}
Final shader, it's full of stars.

08 Downloads

Here are the source files for this project, have at it. Created with Sketch 46.2, Framer v102, and Xcode 9.

App Store preview video.

09 Links

Swift & UIKit Basics

SpriteKit Physics

SpriteKit Shaders

10 Colophon

Made by Justin Rhoades during the summer of 2017. 'How Many Weeks Left?' was last updated on 09.21.2017. This site was last edited on 09.24.2017. I do not mean to offend.