RS-logoRam Shandilya

May 17, 2020 • 4 min read

Building a Design System for iOS - Part 4 - Animations

This is part 4 of the Building a Design System for iOS series. Head over to the previous posts on the in case you missed it.

Animations have the ability to bring a sense of life to the UX and the branding. It's no surprise that a lot of brands have included animation or motion part of their design systems.

As an iOS developer, I'm sure you're no stranger to animations since animations are very much prevalent in the iOS ecosystem. Every developer would've used UIView.animate(...) at some point. But you may have a fair question -

Why include Animations part of my Design System?

Consistency

Imagine having a bounce animation on some buttons and having color fill animation on other buttons. Your users might be thrown off by the inconsistency. It's important to use consistent animations across your app to maintain a familiar, flowing experience. This can be extended to your entire product ecosystem - for example, if you take Microsoft's design system, the way a dropdown is presented on an Xbox UI will pretty much be the same on Outlook.com. This plays an key role in connecting the brand's familiarity.

Flexibility

Design sytems are meant to evolve over time and animation values are bound to change. Similar to fonts and colors, you'll need the animation code to be flexible to changes. Although you might have constants for animation values, it's gonna be hard to trace back all values and tweak them. Having preset values that is defined in your design system will go a long way in shaping the system.

Implementation

The building blocks of an animation are -

  • Duration - how long an animtion lasts
  • Easing - how the animation changes speed over time

Let's jump into them.

Animation Duration

Animation duration, usually takes into account of the complexity of the element you're animating and teh scale of motion. They can usually be categorized in to two -

  • Micro animations - Color fades, button taps, etc.
  • Macro Animations - Covers large amounts of visual ground like side menu reveal, presenting a custom action sheet, etc.

If each of the category is given a slow, medium, fast, we can code it in an Enum like this -

enum AnimationDuration: TimeInterval {
    case microFast = 0.1
    case microRegular = 0.2
    case microSlow = 0.3

    case macroFast = 0.4
    case macroRegular = 0.5
    case macroSlow = 0.6
    
    var timeInterval: TimeInterval {
        return rawValue
    }
}

Depending on your design system, I understand not all animations might fit in to one of those durations, but we can always try our best to compose them with more than one duration.

Easing Curve

Good animations usually mimic some real world metaphor or the other. These usually have a non-linear timing/easing curve. Most easing curve can be defined using a cubic bezier curve.

UIKit has two concrete types - UICubicTimingParameters and UISpringTimingParameters to define a timing curve. You can also create a custom timing curve as well by conforming to the UITimingCurveProvider protocol.

enum AnimationTiming {
    case easeIn
    case easeOut
    case easeInOut
    case spring (velocity: CGVector)

    var curve: UITimingCurveProvider {
        switch self {
        case .easeIn:
            return UICubicTimingParameters(controlPoint1: CGPoint(x: 0.5, y: 0), controlPoint2: CGPoint(x: 1, y: 1))
        case .easeOut:
            return UICubicTimingParameters(controlPoint1: CGPoint(x: 0, y: 0), controlPoint2: CGPoint(x: 0.4, y: 1))
        case .easeInOut:
            return UICubicTimingParameters(controlPoint1: CGPoint(x: 0.45, y: 1), controlPoint2: CGPoint(x: 0.4, y: 1))
        case .spring(let velocity):
            return UISpringTimingParameters(mass: 1.8, stiffness: 330, damping: 33, initialVelocity: velocity)
        }
    }
}

With this setup we can use this on a UIViewPropertyAnimator -

let customAnimator = UIViewPropertyAnimator(duration: AnimationDuration.microSlow.timeInterval, timingParameters: AnimationTiming.easeInOut.curve)

Parting thoughts

As you can see, we've come a long way from using just constants. We're armed with principles that focus on consistency/parity and efficiency.

I hope you enjoyed this series and hope it helps you in giving a head start when you plan to code a design system. I highly encourage in building your system in stages. There is no one-size-fits-all solution for this.


References

•••

This is part four in a series of blog posts highlighting my experience in building different components of a design system for iOS. In case you want to jump to other parts -