What’s New in UIKit Animations in Swift 4 / iOS 11

The new iOS 11 has brought some nice additions and updates for animations in Swift 4. Let’s have a look at what’s new and some stuff that’s worth mentioning about advanced, modern animations currently.

New Animator Behaviors for Animations in Swift 4 / iOS11

There are two new properties for animators (UIViewPropertyAnimator) in Swift 4: Scrubs Linearly and and Pauses On Completion.

Scrubs Linearly

Imagine that you are building an interactive animation, so the user can interact with the view being animated by means of a gesture recognizer.

Probably, your code will be similar to this:

var animator: UIViewPropertyAnimator!

func handlePan(recognizer: UIPanGestureRecognizer) {
   switch recognizer.state {
   case .began:
      animator = UIViewPropertyAnimator(duration: 1.0, curve: .easeInOut)         
         myView.frame = myView.frame.offsetBy(dx: 300, dy: 0)
      }) 
      animator.pauseAnimation()
   case .changed:
      let translation = recognizer.translation(in: myView)
      animator.fractionComplete = translation.x / 300
   case .ended:
      animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)
   default:
      break
   }
}

When the animation gets interrupted, it transitions to a linear curve by default. This is for efficiency reasons, to improve the response of the animation when being modified interactively, and for making the transition smoother when the animation continues (i.e: when the gesture recognizer ends its interaction).

Then, once the animation continues, the animator restores the original curve. Also, both remaining time and animation progress are recalculated.

New in Swift 4 and iOS 11, if you set the animator’s property scrubsLinearly to false, you will disable this curve transition. Thus, the animation will still behave with its original curve or spring behavior during the interaction. As a result, we can achieve some interesting effects.

What’s New In Animations In Swift 4

Additionally, it’s important to note that you can always specify a new curve when the animation resumes after the interaction has ended. Consequently, there are many options and effects you can explore when building your animations.

...
case .ended:
  let timingParameters = UISpringTimingParameters(dampingRatio: 0.8) 
  animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) 
...

Pauses On Completion

Equally important is the new pausesOnCompletion property. By default, when an animation completes, it transitions to an inactive state. Hence, you can no longer modify or interact with the animation.

However,  now if you set the pausesOnCompletion property to true, the animation will stay paused but on an active state. As a result, you will be able to perform operations on the animation such as reversing or adjusting it and triggering it again.

What’s New In Animations In Swift 4

Nevertheless, there’s a caveat you must be aware of. As a consequence of the animation staying active, if you set pausesOnCompletion to true, the animation completion handler will not be called anymore. Instead, you can still be notified of the state of the animation by observing the running keypath of the animator.

animator.addObserver(self, forKeyPath: "running", options: [.new], context: nil)

Animations in Swift 4 / iOS 11 Start as Paused

Previously, when you initialized an UIViewPropertyAnimator, you needed to specify its initial animations. Now, you can start it without any animations, and then use a block to add all the animations at once, so they all run immediately together. Additionally, you can add animations anytime. As a result, instead of escaping, they will run immediately.

let animator = UIViewPropertyAnimator(duration: 2, curve: .easeInOut)
animator.startAnimation()

// do some stuff here

animator.addAnimations {
   // will run immediately
   myView.frame = myView.frame.offsetBy(dx: 200, dy: 0)
}

Animatable Corner Radius And Partial Corners

Certainly one of the most interesting changes for animations, in my opinion, happened in the corner radius property of CALayer. As you may know, this property allows us to specify the corner radius of a view (concretely, of its layer), and is widely used to make round images, for example.

Now, for animations in Swift 4, this property is fully animatable. This is a big plus for animating the size of a circular view while keeping its rounded aspect.

circleView.clipsToBounds = true
UIViewPropertyAnimator(duration: 1, curve: .easeIn) {
   circleView.frame = newFrameValue
   circleView.layer.cornerRadius = newCornerRadiusValue
}.startAnimation()

Additionally, new in Swift 4, we have the possibility to round just some corners of the view. Up until now, I’ve been using a custom Swift class for that, so this is a nice addition.

You can do this thanks to the new property maskedCorners of CALayers, of type CACornerMask.

Some Thoughts On Animations

After the WWDC 2017, we’ve been left with some thoughts on modern, advanced animations for UIKit:

Best Practices For Interrupting Spring Animations

Due to limitations in how the spring animation curves work, and their states throughout the animation, spring animations always animate from their current state. This conflicts with the process of interrupting and continuing with an interactive animation.

Thus, if you need to interrupt a spring animation, these are just some tips and suggestions:

  • First, consider stopping the current animation, creating a new interactive one, and then re-creating a new animation.
  • Also, another option is using critically damped springs (i.e: those with low bouncing rate, dumping ratio 1 or close to 1).
  • Finally, another suggestion is decomposing the X and Y velocities of the animation in two separate animations.

Think Additively When Working With Animations

A very useful tip in my opinion. There are animations that will leave the item in the same state that it was initially. As an example, think of a 360 degrees rotation animation on a view. Because of how animations in UIKit are built, performing this animation directly will have no effect. The view won’t even move. Nothing, niente, nada.

In order to overcome this, you have to divide the animation in separate parts that DO modify the visual aspect of the view, and then chain them together.

Also, another option will be performing the animation with CoreAnimation (CAAnimation), but we of course loose some important high-level benefits like interactivity and scrubbing.

Thus, it’s always a nice idea to solve this situations with an additive approach. The additively animatable properties of UIView are:

 

  • transform
  • frame
  • bounds
  • center
  • position

Let’s see an example of a rotation performed in 100 steps of 𝛑/2.

let animator = UIViewPropertyAnimator(duration: 5, curve: .easeInOut, animations: {
   for _ in 0..<100 {
      let rotation = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 2.0))
      square.transform = square.transform.concatenating(rotation)
   }
})
animator.startAnimation()

Of course, you need to observe some efficiency and optimization aspects when building additive animations. Nevertheless, it’s a nice technique to apply in scenarios where a direct animation will not work properly.

In Conclusion

In this article, I described what’s new in animations in Swift 4 and the new iOS 11. Overall, nice additions and tweaks that help us have more control over our animations.

If you want to see some examples of animations in Swift 4, please refer to the tutorial Advanced UIKit Animations in Swift, or the sample code found here.

Comments(9)

Leo
July 23, 2017 At 2:46 pm

The title seems to be misleading. I would better say what’s new in animations in UIKit because when I opened the web page, at first I thought what is the connection between Swift 4 language capabilities and animations…

Tof
July 25, 2017 At 2:46 pm

Agree with leo

    Ignacio Nieto Carvajal
    July 25, 2017 At 2:46 pm

    Agreed, I changed it. Hope the title is more appropriate now! 😉

KK
August 2, 2017 At 2:46 pm

The pausesOnCompletion is really strange.
When true, the animation continues.

Just see this name, think about that when you pauses on completion, the animation just move on ?
So strange, isn’t it?

    Ignacio Nieto Carvajal
    August 8, 2017 At 2:46 pm

    Yes, I know what you mean.

J. Kim
November 27, 2017 At 2:46 pm

These are not new features of Swift 4 but of iOS 11.

    Ignacio Nieto Carvajal
    November 28, 2017 At 2:46 pm

    Hi there J. Thanks for commenting. Yes, I know, and it’s clearly indicated in the post, but just wanted to emphasize that the tutorial covers Swift 4. However, it’s a good point and I have modified the title to make it clearer. Thanks! :)

BAGELS
June 15, 2018 At 2:46 pm

This link doesn’t work;

https://digitalleaves.com/advanced-uikit-animations-swift/

    Ignacio Nieto Carvajal
    June 17, 2018 At 2:46 pm

    Thank you Bagels, I removed the link. We are updating our website and will be publishing more stuff soon. Thanks again!

Leave a Comment

sing in to post your comment or sign-up if you dont have any account.