Adding Bounce to Your UIViews: The Joy of Damped Harmonics in iOS 7 Development
Although you can always roll your physics-based animations, UIKit now offers one exceedingly handy built-in utility based on damped harmonics. The
animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:
method is a mighty mouthful, but this single method offers an amazing way to add follow through to interface elements with a minimum of fuss and bother.
Instead of just animating a view linearly to some point on the screen, this new spring-based animation enlivens the transition. The call enables a view to bounce a little (or a lot) as it approaches its targeted position. Based on a damped harmonic spring, you specify the animation’s duration, a damping constant, and an initial view velocity as the view begins participating.
Harmonics in Action
Video 1 demonstrates this call as it is used in a simple interface. The video consists of three separate animations. Each starts with a view placed just offscreen and animates it to the center by updating a position constraint. The bounce option uses the spring method for the entire animation, moving the view from its initial point. It applies a damping constant of 0.2 resulting in an energetic entry.
- (void) bounceExample { // Setup [self setupView]; // Animate [UIView animateWithDuration:duration delay:0 usingSpringWithDamping:damping initialSpringVelocity:0.0f options:0 animations:^{ primaryConstraint.constant = 0; [self.view layoutIfNeeded]; } completion:nil]; }
Video 1. These examples demonstrate UIKit’s new damped harmonic animations.
The velocity option uses a traditional linear animation for the first three quarters of the distance. It then applies the spring to the final quarter, feeding the current linear velocity into the initialSpringVelocity parameter. This produces a more bounded result, with the view bouncing less noticeably. The virtual spring stretches only one-quarter as far, and the final animation reflects that.
- (void) velocityExample { // Setup [self setupView]; // Move toward center CGFloat distance = primaryConstraint.constant; CGFloat firstDistance = 0.25f * distance; CGFloat firstDuration = 0.25f * duration; CGFloat velocity = firstDistance / (fabs(distance) - fabs(firstDistance)); [UIView animateBlockingWithDuration:firstDuration animations:^{ primaryConstraint.constant = firstDistance; [self.view layoutIfNeeded]; } completion:nil]; // Bounce [UIView animateWithDuration:(duration - firstDuration) delay:0 usingSpringWithDamping:damping initialSpringVelocity:velocity options:0 animations:^{ primaryConstraint.constant = 0; [self.view layoutIfNeeded]; } completion:nil]; }
The slide option shows the old way of doing things. It performs a standard linear animation for the entire distance without any harmonic oscillation. In the video it contrasts the default animation style with the new damped harmonic versions.
- (void) slideExample { // Setup [self setupView]; // Animate [UIView animateWithDuration:duration animations:^{ primaryConstraint.constant = 0; [self.view layoutIfNeeded]; }]; }
The 0.2 damping constant used in Video 1 demonstrates the difference between the full and partial animations. For most animations you’ll want to dial up that damping somewhere closer to a default 0.5 value, as in Video 2.
Video 2. The midway damping point of 0.5 provides a common working target.
Building a Drawer
Drawers, that is, views that slide in and out from your primary interface, provide a great match to spring-based animations. Varying the damping constant enables the drawer to respond to various states like successful and unsuccessful opening requests with differing energies. The degree of energy you use offers hints regarding the success or failure of each action as well as their natural state. These small tweaks to parameters create distinct user experiences.
The drawer in Video 3 uses three different constants. When opening, it animates with a damping set to 0.4, with noticeable energy. In closing, the damping is increased to 0.6, reducing the oscillation more quickly. The failure sequence uses a relatively extreme 0.25 constant, mimicking the physics of an old-fashioned window blind flapping back to its rolled up position.
Video 3. A spring-based drawer view.
As you see in the video, spring animations works best when a view falls back to a natural place or when that natural place updates due to user interaction. In this example, a user pulls out a drawer until it passes some boundary, at which time the app knows to update that view to its “open” position. If the drag fails to pass that point, the drawer flaps backward dramatically.
Extending Animation Vocabulary
The animations you’ve seen so far in this write-up have shown a view that acts as if it is attached to a spring. Your animations aren’t limited to position changes. As Video 4 shows, you can tweak any animatable property with this approach. In Video 4, you see examples of scale, transparency, and rotation animations applied through damped oscillation. Although some properties (rotation and scale in this case) produce more effective results than others (alpha levels), think creatively and don’t be afraid to animate more than one effect at a time.
Video 4. Spring animations work with any animatable properties.
Wrap Up
Just because a tool is single-purpose doesn’t mean you won’t end up using it a lot. The UIView spring animator, which performs animations using a timing curve based on the motions of a physical spring, provides an extremely handy tool. By incorporating its animations into your application, you can present views with a dynamic range of motion that can liven up your UIs and please your users.