The Evolution of WURM UI

WURM is a generative mobile app that I first released at the end of 2010. Unwittingly, it has become an on-going pet project that I still keep tinkering with. Part of the reason is that I keep learning the iOS platform. When I started making the app I knew almost nothing about Objective-c or developing in the OSX environment. In hindsight, it actually seems a miracle that I even got it on the App Store given how little I truly understood about what I was doing. Coding on blind faith was more like it. But it was fun and now, over two years later, I feel pretty comfortable around the iOS. 

The other part of it became the UI. The touch interface was such a novel and exciting canvas that my inner designer couldn’t get enough of it. Still can’t. If I had to guess, the UI probably takes up the biggest chunk of my process because, unlike coding, there’s not a lot of logic to it. It’s very organic and I usually have to “see it to feel it”. That often takes many iterations, and even when I do settle on something, I’m never 100% sure of it. But I ship anyway, knowing that things will inevitably change in the next update. It’s the process itself that I seem to get hooked on. The truth might be there somewhere..

Here’s WURM design timeline to date (iPad version not shown).

Version 1.0: First official version, designed using mostly default controls.

WRM-UI-1_0a   WRM-UI-1_0b


Version 1.4: Custom-designed controls; new shuffle button; also purchased my first iPad, which led to a universal UI adaptable in all orientations.

WRM-UI-1.4a   WRM-UI-1.4b


Version 1.7: By this point I designed a bigger dashboard for the iPad but the look of UI elements remained the same, so I continued refining.

WRM-UI-1.7a   WRM-UI-1.7b


Version 2.0: I had new ideas for the app, which required a significant change in the programming logic, which in turn, forced a new UI overhaul.

WRM-UI-2.0a   WRM-UI-2.0b


Version 2.1: I’m the biggest user of my app and by this point I craved something fresh; decided to try a lighter and simplified look.

WRM-UI-2.1a   WRM-UI-2.1b


Geometry Daily

tumblr_m9w5rm8Vwu1r9nwnbo1_500 tumblr_manybxSDVr1r9nwnbo1_500 tumblr_metwlm7hS61r9nwnbo1_500  tumblr_mlz7n6IAiz1r9nwnbo1_500tumblr_meymvrQrWE1r9nwnbo1_500tumblr_mhpolrnRTk1r9nwnbo1_500

Recently I came across a minimalist tumblog Geometry Daily by German graphic designer Tilman. Tilman started the project during a year-long paternity leave as way to keep his creative muscles flexing while fulfilling dad duties. Thanks to his commitment and consistency, a seemingly humble side project has grown to be wildly successful and inspired lots of creatives around the web.

I’m happy to join their ranks as his style and philosophy certainly sing down my alley. I’ve been a fan of geometrics since grade 5 geometry class, long before I considered them design elements. And the fascination persists to this day. If someone were to ask me why, I might as well point them to Tilman’s words:

I find endless beauty just in the way geometry works. It feels like geometry has only a small set of rules, yet these create so much complexity that we will never be able to see even a small fraction of what is possible.

True words. It’s the complexity hidden in simplicity that’s very compelling. Especially the Zen kind of simplicity that Tilman seems to channel in his sketches. I almost want to think of them as visual haiku or something.

If you like the work and want to get some geometric Zen on your walls, consider buying a silkscreen or a digital print.

How to synchronize UIView and CALayer animations

Core Animation layers come very handy for rendering simple secondary views. One thing I really love about them is the implicit animations – they often add that nice-to-have touch to something I may not have bothered with. However, things can get not so nice when trying to pair them up with regular UIView transitions. I discovered this recently when trying to re-size the frame of a UIView and the corresponding frame of a CAGradientLayer behind it. The default result simply did not look good. By the nature of being implicit, layers follow their own inner instructor and ignore UIKit commands. They are also only about 0.25 seconds in duration, which works for smaller changes but is often not enough for transforming bigger elements. For that reason, simply matching the same duration on the UIView was not the answer. Well, not the full answer..

The first step in overriding implicit animations was to create a CABasicAnimation and wrap it inside a CATransaction block. Then the matching trick comes in and you need to make sure that the duration and the ease curve are equivalent in both blocks. So in this case I used kCAMediaTimingFunctionEaseOut in CATransaction with the corresponding UIViewAnimationOptionCurveEaseOut in UIView.

And at last, a perfect animation unison was found.

float duration = 0.5;////////////////////////////
// CALayer part
///////////////////////////[CATransaction begin];
[CATransaction setAnimationDuration:duration];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];

CABasicAnimation *myAnimation = [CABasicAnimation animationWithKeyPath:@"frame"];
[myAnimation setToValue:[NSValue valueWithCGRect:myNewFrame]];
[myAnimation setFromValue:[NSValue valueWithCGRect:[myLayer frame]]];

[myLayer setFrame:myNewFrame];
[myLayer addAnimation:myAnimation forKey:@"myAnimationKey"];
[CATransaction commit];

// UIView part
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseOut
                         myView.bounds = myNewFrame;    

                     completion:^(BOOL finished) {