Your Spring Animations Are Bad
(And It’s Probably Apple’s Fault)
In early 2011, the iPad app-slash-book Our Choice built by the crackerjack team at Push Pop Press launched. Its content was created by Al Gore but it was unlike any other ebook at the time: it was a completely immersive and interactive experience where the reader directly engaged with the content by blowing clouds (you blew into the microphone!), slinging photos and swiping at charts.
The app was released for iOS 4 but was so ahead of its time, so futuristic and genre-defining, that if it had never been built until 2015 and was finally released for iOS 8 and looked exactly the same it’d probably still win an Apple Design Award. It was that incredible.
The app was designed and built by Mike Matas, Kimon Tsinteris and Austin Sarner, and was one of the first apps for the iPad or iPhone to extensively use the physical properties of springs to guide interactivity and motion. For example, as a user dragged a photo around the screen, the photo was tugged back almost imperceptibly by an invisible but familiar force: a taut spring. When you let the photo go, it immediately sprung back into its original place with a satisfying boingoingoingoing motion that made you want to do that gesture over and over. (They patented this behavior.)
“[Austin was] completely obsessed with springs” says Phil Ryu,
creator of Clear and former roommate of Sarner.
Interactivity guided by the physical properties of springs and their unmistakably wobbly motion was a huge hit. At WWDC in 2011, Our Choice won a coveted Apple Design Award. Unfortunately, Push Pop Press never did publish another incredible ebook because just 2 months after winning an ADA, Facebook gobbled them up. And that patent? Facebook now owns it.
iOS and Spring Animation APIs
When iOS 6 came out, and private headers were dumped, there were a number of interesting classes discovered, and one of the most interesting was CASpringAnimation.h. It was an internal class that Apple had created to aide in the development of spring motion animations, something that Apple had started to use sparingly in certain corners of iOS. It was private, not for developers to use.
The header revealed a simple class that extended CABasicAnimation and had the following properties: damping, mass, stiffness and velocity. It was ostensibly used in lieu of a simple Core Animation object (that could only use cubic bezier easing for its timing function) to produce motions that mimicked the natural, physical motion of a mass-damper spring system.
Fast-forward a year later to June 2013 when Apple unveiled iOS 7 and the complete overhaul of the iOS user interface. Some people (myself included, see the embedded tweet below) thought that Apple might make CASpringAnimation a public class that developers could utilize, but instead, Apple unveiled the monster UIKit Dynamics framework that let iOS developers utilize gravity, collision detection, and more, to make interfaces feel more interactive.
Unfortunately, many developers think that UIKit Dynamics missed the mark. It didn’t allow for simple spring motion animations to be created in the vein of CASpringAnimation, but instead developers needed to initialize a series of UIDynamicItemBehaviors tweaked just so to produce motions that resembled a spring. These effects are not part of the Core Animation chain, but rather implemented using the separate physics simulation system of the UIDynamicAnimator object. In short, the way that UIKit Dynamics enables spring-based motion is far from ideal.
Fortunately, Apple did add a new method to the UIView block-based animation category, one that let developers simply add spring motion to interfaces without jumping through any complex hoops.
This method looks a lot like the block-based animation methods on UIView that developers were already using, but adds 2 key parameters: spring damping and initial velocity. The spring damping value is expected to be a value between 0 and 1, where a value close to 0 makes the animation super springy, and a value close to 1 will have no spring motion at all. The initial velocity parameter helps in situations where a view is already moving before an animation is applied to it, so you can provide a velocity input to match its current velocity and ensure a smooth start to the animation.
The problem with this method may not be obvious at first glance, so here are some animation examples built using this API.
So, although the animations above are indeed spring-like, they don’t actually move in a real, natural spring motion governed by the true physics of a spring. Their movement looks a little artificial compared to the animations below which do move in perfect accordance with a spring. (The final animation shows the case of a spring being overdamped which means it doesn’t oscillate at all.)
The issue is that the block-based animation method Apple provides developers (where you provide a spring damping value between 0–1) needs a duration value. You essentially have to guess what the appropriate duration should be to make the spring motion settle naturally. If your element is moving 100px across the screen, and you choose a damping of .3, the only way to figure out the true duration of the movement is to do math on your own. If you just plug in a random duration, the feel of the entire animation will be off.
This is the reason that so many apps that use spring animation feel weird. It’s because they’re using Apple’s spring animation API, but if you don’t jump through hoops to reverse-derive the appropriate duration value, whatever duration value entered will make the spring animation feel too fast, too springy or just plain unnatural. I’d say that it’s nearly impossible to use Apple’s spring animation API and end up with a spring motion that feels like a perfect recreation of a natural spring.
In a true spring-based animation system, the physical properties of the spring (damping, stiffness and mass) will produce a motion that will settle down at the final value once the mechanics of the system arrive at the final value. If you want the duration of your animation to be shorter, then you can tweak the properties of the spring so that it reaches the final value quicker, typically by increasing the damping property of the spring. By not artificially manipulating the overall duration of the spring motion, you’re letting the object you’re animating move as if it would in the natural world with actual spring forces governing its complete motion and duration of motion.
In fact, CASpringAnimation, Apple’s private class for spring animation, does exactly this. You plug in various properties of the spring, and the duration is derived from the system’s properties, thus animating objects in a true spring-like motion with no artificial duration value to mess it up.
Andy Matuschak, the lead mobile engineer at Khan Academy and former engineer on the UIKit team at Apple, was one of the creators of the block-based springy UIView animation method we’ve been talking about. Now that he’s left Apple, he’s had some interesting conversations on Twitter about the method in question.
From the full conversations, it seems that Andy admits that the API is not clear regarding the interplay between the duration and damping parameters, and that providing developers more spring properties to tweak would have been helpful. Grant Paul (@chpwn) from the above conversation, says that he needs to reverse the spring motion equation in order to derive a duration that makes the motion settle naturally.
Real Spring Motion In Your Apps
If Apple’s springy UIView animation method easily produces artificial-feeling motion, then what other options are there?
Once developers realized that iOS 7's animation APIs were lacking, a number of solid spring animation frameworks have popped up. They all produce real spring motion with no duration parameter needed: their animation durations are calculated using the properties of the spring system that you set.
Here are some of my favorites.
JNWSpringAnimation. You set damping, stiffness and mass, and it will generate keyframes for your animation. Use it just like you’d use any CAKeyframeAnimation in your code. The framework comes with a nifty Mac app that lets you preview how various spring parameters will affect your animation.
Facebook Pop. Pop is the framework that Facebook uses to power the animations in their app Paper. It’s also authored by Kimon Tsinteris, one of the creators of the Our Choice iPad app. Pop works differently from JNWSpringAnimation as it doesn’t use Core Animation, it relies on a timer firing every 1/60th of a second (CADisplayLink) to govern the motion of elements so it can recalculate their position easily if a gesture interrupts the animation.
RBBAnimation. Another keyframe-based animation framework, but this one actually has a fully reverse-engineered version of CASpringAnimation built into it if you want to build animations like Apple engineers do.
INTUAnimationEngine. This animation engine combines ideas from Pop (using CADisplayLink) with a simpler, block-based API that lets you be notified of the progress of your animation each step of the way and adjust the motion as needed.
Spring animations have gotten a bad rap, and one reason why is because when implemented poorly, they just feel wrong. They mess up the feel of the entire user interface. With Apple’s spring animation APIs, it’s easy to add spring animations to your apps, but when you have to guess at a duration parameter, the motion will never feel right. If you do choose to use spring animations, you should look into the frameworks listed above instead of using Apple’s APIs because they’ll produce a better, more natural-feeling motion.