My book on iOS interface design, Design Teardowns: Step-by-step iOS interface design walkthroughs is now available!
Making your animations POP
So earlier this week, Facebook open sourced its animation framework called Pop. Credited with powering all the animations and transitions in Paper, it is definitely one step towards the era of next-generation interfaces.
Dynamism
Conventional animation is static animation. The arbitrarily set duration scales animations in the time dimension and removes realism from our interfaces.
Pop provides two sets of dynamic animations, namely spring and decay. These animations don't take a duration parameter ( decay doesn't even allow you to set a stop-point.) They just play out until they stop and feel much closer to the physical world than static animations.
Velocity
The spring and decay animations can also take a velocity, typically off the back of a UIGestureRecognizer
. This means that we are not simply watching a movie after our gesture ends but the animation is unique to nuances of the preceding gesture.
Here's an example of a Pop animation:
POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBounds];
anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 400, 400)];
[layer pop_addAnimation:anim forKey:@"size"];
It's worth noting it's very similar to Core Animation-style syntax. In my opinion though, that's a step backwards.
Verbosity
By now, we're all spoilt by the block-based animations in UIKit. Having to create animations at this level of verbosity is simply ridiculous.
Pop, however, solves one of the issues plaguing Core Animation. Previously, the property being animated is specified by an arbitrary string called a key path . Pop now forces you to use a string constant, such as kPOPLayerBounds
, or declare your own animatable properties. At least you are no longer at the mercy of typos.
Boxed Values
Another sticking point is that the compiler is unable to provide any type checking at all. All the start- and stop-points are boxed in NSNumber
or NSValue
equivalents.
An Experiment
These problems can be solved rather effectively through use of a proxy (similar to the appearance proxy in UIAppearance.) The proxy can observe method calls (invocations) and execute the relevant boilerplate code behind the scenes.
Because the proxy returns instancetype
, Xcode can provide the same code completion and type checking on values. Contrast the above code with the following:
layer.spring.bounds = CGRectMake(0, 0, 400, 400);
This is a more concise way of creating the animation where spring is the animation proxy which also happens to tell us what the type of the animation is. Of course, we can do similarly for linear
, easeIn
, easeOut
, easeInEaseOut
and decay
.
If you're interested to try this out, check out the repository.
If you liked this post and want to receive updates on my upcoming book on practial interface design for iOS, subscribe to my mailing list (your email will not be shared):