Adding vibrancy to animations

A lot of animations on iOS look bouncy and feel natural. For instance, when an object starts moving in the real world, it rarely does so smoothly. Often, something moves because something else applied an initial force to it, causing it to have a certain momentum. Spring animations help you to apply this sort of real-world momentum to your animations.

Spring animations are usually configured with an initial speed. This speed is the momentum an object should have when it begins moving. All spring animations require a damping to be set on them. The value of this property specifies how much an object can overflow its target value. A smaller damping will make your animation feel more bouncy because it will float around its end value more drastically.

The easiest way to explore spring animations is by slightly refactoring the animation you just created for the drawer. Instead of using an easeOut animation when a user taps the Toggle Drawer button, you can use a spring animation instead. The following code shows the changes you need to make to setUpAnimation():

func setUpAnimation() {
  guard animator == nil || animator?.isRunning == false
    else { return }

  let spring: UISpringTimingParameters
  if self.isDrawerOpen {
    spring = UISpringTimingParameters(dampingRatio: 0.8, initialVelocity: CGVector(dx: 0, dy: 10))
  } else {
    spring = UISpringTimingParameters(dampingRatio: 0.8, initialVelocity: CGVector(dx: 0, dy: -10))
  }

  animator = UIViewPropertyAnimator(duration: 1, timingParameters: spring)

  animator?.addAnimations { [unowned self] in
    if self.isDrawerOpen {
      self.drawer.transform = CGAffineTransform.identity
    } else {
      self.drawer.transform = CGAffineTransform(translationX: 0, y: -305)
    }
  }

  // ...
}

When you implement a spring animation, you use a special initializer for UIViewPropertyAnimator. Since you can't pass animations to this initializer, you must add them by calling addAnimations(_:). Adding spring animations did not require a considerable code change, but try running the app and tapping on the toggle button. The drawer will now feel more realistic because its animation curve is not as static as it was before.

Play around with the values for the spring damping and the velocity, if you use some extreme values you'll get interesting results. Keep in mind that the damping should be a value between 0 and 1 and that a value closer to 1 will make your animation bounce less.

The animation that is executed by the pan recognizer doesn't feel great at this point. It's very static and doesn't take into account how fast a user is panning on the drawer. When the user ends their pan gesture, you can set the sprint timing's initialVelocity based on the actual pan velocity. This will make the animation feel even more realistic because it will now use the actual pan speed as the initial speed for animation:

@objc func didPanOnDrawer(recognizer: UIPanGestureRecognizer) {
  // ...
  default:
    drawerPanStart = 0
    let currentVelocity = recognizer.velocity(in: drawer)
    let spring = UISpringTimingParameters(dampingRatio: 0.8, initialVelocity: CGVector(dx: 0, dy: currentVelocity.y))

    animator?.continueAnimation(withTimingParameters: spring, durationFactor: 0)
    let isSwipingDown = currentVelocity.y > 0
    if isSwipingDown == !isDrawerOpen {
      animator?.isReversed = true
    }
  }
}

As you've just seen, the use of spring animations can benefit your animations and they are not very hard to add to your apps. While they might not always be the best solution, their ease of implementation makes spring animations a worthy candidate to experiment with to determine whether your animation needs a spring.

While the animation you have just implemented is pretty lifelike and realistic, your animations might need even more realism. The next section covers UIKit Dynamics, which is a special method of animating objects that uses a physics engine and can detect collisions between objects.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset