Test whether a UIView is in the middle of animation
Is there any way to tell if a UIView is in the middle of an animation? When I print out the view object while it is moving I notice that there is an "animations" entry:
search bar should end editing: <UISearchBar: 0x2e6240; frame = (0 0; 320 88); text = ''; autoresize = W+BM; animations = { position=<CABasicAnimation: 0x6a69c40>; bounds=<CABasicAnimation: 0x6a6d4d0>; }; layer = <CALayer: 0x2e6e00>>
When the animation has stopped and I print the view, the "animations" entry is now gone:
search bar should end editing: <UISearchBar: 0x2e6240; frame = (0 0; 320 88); text = ''; autoresize = W+BM; layer = <CALayer: 0x2e6e00>>
Solution 1:
A UIView
has a layer (CALayer
). You can send animationKeys
to it, which will give you an array of keys which identify the animations attached to the layer. I suppose that if there are any entries, the animation(s) are running. If you want to dig even deeper have a look at the CAMediaTiming
protocol which CALayer
adopts. It does some more information on the current animation.
Important: If you add an animation with a nil
key ([layer addAnimation:animation forKey:nil]
), animationKeys
returns nil
.
Solution 2:
iOS 9+ method, works even when layer.animationKeys
contains no keys:
let isInTheMiddleOfAnimation = UIView.inheritedAnimationDuration > 0
From the docs:
This method only returns a non-zero value if called within a UIView animation block.
Solution 3:
Animations are attached in fact to the underlying Core Animation CALayer
class
So I think you can just check myView.layer.animationKeys
Solution 4:
I'm not sure of the context of the question but I had was attempting to find out if a view was animating before starting a second animation to avoid skipping. However there is a UIView animation option UIViewAnimationOptionBeginFromCurrentState
that will combine the animations if necessary to give a smooth appearance. Thereby eliminating my need to know if the view was animating.