Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use UIView animation, CABasicAnimation and UIViewPropertyAnimator?

I wanted to know in which scenarios we should use any of them as the best fit?

In the following blog https://www.hackingwithswift.com/ios10, the example written in "Animations revisited" section, can we re-apply the same requirement using "CABasicAnimation", meaning the pause and resume animations?

From what I have gathered, when we use UIView.animate(...) method, it returns a void, so we won't be able to control the animation before its completion, cause we do not get a return value to work upon as we get in UIViewPropertyAnimator(also,here we have "isRunning" to check the progress of animation.) Also in CABasicAnimation, we do not have any progress check for running animation. Please correct me if my assumptions are wrong. Thank you.

like image 703
Raj Avatar asked Mar 15 '17 06:03

Raj


People also ask

Is UIView animate asynchronous?

UIView. animate runs on the main thread and is asynchronous.

Does UIView animate need weak self?

You don't need to use [weak self] in static function UIView. animate() You need to use weak when retain cycle is possible and animations block is not retained by self.

Does UIView animate run on the main thread?

The contents of your block are performed on the main thread regardless of where you call [UIView animateWithDuration:animations:] . It's best to let the OS run your animations; the animation thread does not block the main thread -- only the animation block itself.

What is animation in Swift?

Animations can add visual cues that notify users about what's going on in the app. In iOS, animations are used extensively to reposition views, change their size, remove them from view hierarchies, and hide them.


1 Answers

TLDR

  • UIView's animation methods allow easy and basic animation of UIView properties, with little code footprint.
  • Core Animation allows animating of the underlying layer's properties.
  • UIViewPropertyAnimator allows complex and dynamic animation of UIView properties.

Background

All of those API's are great, and they all have slightly different use cases. Before getting into them, it's good to understand that

  1. All animations on iOS are run using Core Animation. UIKit's block-based animation methods are simply a convenience feature.
  2. While UIKit and Core Animation both provide animation support, they give access to different parts of the view hierarchy.

With UIKit, animations are performed using UIView objects. The properties available for animation using UIKit are:

  • frame
  • bounds
  • center
  • transform
  • alpha
  • backgroundColor
  • contentStretch

While Core Animation gives access to the view's underlying layer, exposing a different set of properties as outlined below (it's worth noting that because views and layers are intricately linked together, changes to a view's layer affect the view itself):

  • The size and position of the layer
  • The center point used when performing transformations
  • Transformations to the layer or its sublayers in 3D space
  • The addition or removal of a layer from the layer hierarchy
  • The layer’s Z-order relative to other sibling layers
  • The layer’s shadow
  • The layer’s border (including whether the layer’s corners are rounded)
  • The portion of the layer that stretches during resizing operations
  • The layer’s opacity
  • The clipping behavior for sublayers that lie outside the layer’s bounds
  • The current contents of the layer
  • The rasterization behavior of the layer

Refer to this Apple Developer document for more reading on this.


UIView's animation methods

These are still the easiest to use in my opinion. Very straight forward API without making too big of a code footprint. I use this either for simple fire-and-forget animations (such as making a button pop when selected), or when I want to make a complex keyframe animation since its keyframe support is great.

Example:

UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseOut, animations: {
    button.transform = .init(scaleX: 1.1, y: 1.1)
}

Core Animation

Perhaps a bit less straight-forward to use, but you need it whenever you want to animate layer properties instead of view properties, as mentioned above. Examples of these are corner radius, shadow, and border.

Example:

CATransaction.begin()
CATransaction.setAnimationDuration(0.5)
CATransaction.timingFunction = .init(name: .easeOut)

let cornerAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.cornerRadius))
cornerAnimation.fromValue = 0.0
cornerAnimation.toValue = 10.0
button.layer.add(cornerAnimation, forKey: #keyPath(CALayer.cornerRadius))

CATransaction.commit()

For a more detailed take on Core Animation, this is a great article (not written by me).


UIViewPropertyAnimator

Added in iOS 10, as the name suggests this is another view-based animation API. There are a few things that make it different from UIView's animation methods, the main ones being that it supports interactive animations and allows modifying animations dynamically. You can pause, rewind, or scrub an animation, as well as adding more animation blocks on the go or reversing the animation while it's playing, which makes it quite powerful. I use this when I want an animation to be controlled by the user. The scrubbing works by setting a fractionComplete property on the animator object, which can easily be hooked up to a pan gesture recognizer or a force touch recognizer (or even a key using KVO).

As mentioned, you can also store a reference to a UIViewPropertyAnimator and change its animations or completion blocks during the animation.

Example:

// Create an animation object with an initual color change animation
let animator = UIViewPropertyAnimator(duration: duration, curve: .linear) {
    button.backgroundColor = .blue
}

// At any point during the runtime, we can amend the list of animations like so
animator.addAnimations {
    button.transform = .init(scaleX: 1.1, y: 1.1)
}

animator.startAnimation()

}

Worth noting is that you can actually use UIView.animate and UIView.animateKeyframes from within your UIViewPropertyAnimator animations blocks, should you feel the need to use both.

If you want a more detailed example of UIViewPropertyAnimator, I wrote a small tutorial on it here.

like image 133
Daniel Larsson Avatar answered Nov 11 '22 21:11

Daniel Larsson