UIView Animation Sequencing and Grouping Techniques

UIView animation with RZViewActionsYou’ve got an idea for an awesome, jaw-dropping animation that you’re dying to implement in your app… but where to begin? This post analyzes the primary animation options available to us in iOS, and introduces RZViewActions, which is designed to eliminate nested animation code blocks and make composite animations as painless as possible.

Core Animation

Core Animation is a powerful animation framework designed to operate on CALayers, the backing objects for most UIViews. Almost any property of a layer can animated using a CABasicAnimation, which is the primary building block for CA animations. For example, to fade out a view with a nice animation curve:

Yikes. And that was just to animate one layer property. When using Core Animation, each property must be animated with a separate CAAnimation, meaning a complex animation can end up being hundreds of lines of code.

Beyond the Basics

Luckily Core Animation provides CAKeyFrameAnimation to assist with keyframe animations (again, you’ll need one for each property animated), and CAAnimationGroup to run several animations concurrently. These constructs help manage some complexity, but are still cumbersome to configure. CAAnimationGroup especially has some (documented) gotchas:

“… animations are clipped to the duration of the animation group. For example, a 10 second animation grouped within an animation group with a duration of 5 seconds will only display the first 5 seconds of the animation.”

“The delegate and removedOnCompletion properties of animations in the animations property are currently ignored. The CAAnimationGroup delegate does receive these messages.”

Note that CAAnimations use delegation to give callbacks when the animation starts or stops. However, the animationDidStart: and animationDidStop: delegate methods don’t provide the key the animation was run with, so each animation really needs its own delegate. Alternatively, this category provides a block-based approach to callbacks. The moral is that although Core Animation is powerful, many developers prefer the friendlier, higher-level frameworks where possible.

UIView Animations

The UIView animation methods are what developers are most familiar with. They operate on properties of UIViews, and use Core Animation under the hood. These animations are block-based and are much simpler to configure. This code performs the same fade animation shown above:

Nice. Note that multiple properties can be animated from within the same animation block. However, only implicitly animatable properties can be animated in this way. Most of the built-in properties support implicit animation, but refer to the documentation for an individual property if you’re unsure. There are also several variations of this method, which can be used to specify a delay, animation curve, and block to be called when the animation is complete. UIView animations are familiar and incredibly easy, so are likely the go-to animation option for most developers.

But what if you have a really complicated animation? I frequently see animation sequences accomplished with UIView animations nested within the completion blocks of others, resulting in ridiculous indentation levels and zero readability, e.g.

UIView Keyframe Animations

iOS7 introduced a less-known alternative, animateKeyFramesWithDuration:delay:options:animation:completion:. For example:

UIView keyframe animation is great for simple sequences and groups of animations assuming your app is iOS7+. The cons are:

  • They can’t be nested within themselves, which limits the complexity of the animation.
  • No support for “springy” animations i.e. animate...usingSpringWithDamping:initialSpringVelocity:...
  • Forces you to deal with relative times.

Additionally, reuse of animation blocks is difficult unless you want to define and store each animation block.

Introducing RZViewActions

RZViewActions is a category on UIView that allows developers to define animations semantically, and provides additional structure to UIView animations. Inspired by SKAction from Sprite Kit, RZViewActions provides methods for creating individual animations, sequencing them, and grouping them. Like with SKAction, sequences can be added to groups, and groups can be added to sequences, meaning your animations can become arbitrarily complex.

Sequences and Groups

Each RZViewAction performs one animation block, but the actions can be combined in either a sequence, which runs the actions one after the other, or a group, which runs the actions concurrently. Consider the following animation:

From reading the action definitions it is immediately obvious, even to a non-animator, what this composite animation does, and there are no nested blocks.
Even an action like the one shown above may be just a piece of a larger animation. This particular action drives the title heartbeat in the following example:

UIView animation with RZViewActions

The animation structure for this demo looks like this:

RZViewActions Demo Animation Structure

It may look complicated, but this animation is constructed from simple groups and sequences, which themselves are composed of individual RZViewAction objects. Breaking a complex animation into understandable pieces is crucial for both readability and maintainability. This animation is part of the RZViewActions demo project, and the public repository lives here. The code is available under the MIT license, and is compatible with iOS 4.0 and later.

In Closing

We always want a dynamic and engaging UI, but sometimes achieving the perfect animation can become a sticking point. iOS provides several ways to accomplish this task, so it generally isn’t necessary to delve into Core Animation. UIView animations are sufficient for most tasks, but become increasingly difficult to maintain as complexity increases. Finally, RZViewActions provides a more intuitive structure that allows for increased complexity without increased pain.

It is up to you as a developer to choose the best tool for the job, but I encourage you to consider code maintainability. And instead of fearing animation as a thing of mystery, embrace it as an opportunity to provide an unexpected and delightful experience for your users.

Interested in joining the Raizlabs team making great software? We’re hiring in Boston and SF.

4 thoughts on “UIView Animation Sequencing and Grouping Techniques”

  1. Hi Rob,
    I implemented a animation sequence with your RZViewAction, which works quite well!
    But since the animation is quite long, I want to be able to stop it before it is finished. Is there a way to do that?

    Thanks in advance,
    Julian

  2. Hi, thanks for this library. How can I use this for forever-repeating animation ?

    • You can use UIViewAnimationOptionRepeat, just like with normal UIView animations.

  3. Hello,

    I love the way to you explained the keyframe animation specially by giving a demo app and explained it in a very simpler way 🙂 .
    I have a question regarding the attached sample application.
    How to stop ongoing animation? let suppose animation started (title animation, tap label activity indicator, and copy right label animation).As it takes time to get it done completely and in-between If I want to stop this ongoing animation group it should stopped immediately and once that animation stopped all subviews(title label,tap label and copy right)should be in their right places.

Leave a Comment