可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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>>
回答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.
回答2:
Animations are attached in fact to the underlying Core Animation CALayer
class
So I think you can just check myView.layer.animationKeys
回答3:
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.
回答4:
There is a hitch with the animationKeys trick.
Sometimes there could be a few animationKeys lingering after an animation is completed.
This means that a non-animating layer could return a set of animationKeys even if it isn't actually animating.
You can make sure that animationKeys are automatically removed by setting an animation's removedOnCompletion property to YES.
e.g.
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"aPath"];
animation.removedOnCompletion = YES;
If you do this for all the animations you apply to your layer, it will ensure that when the layer isn't animating there are no animationKeys present.
回答5:
Some of these didn't work for me. The reason for that is that these animations are asynchronous.
What I did is defined a property
@property BOOL viewIsAnimating;
And in my animation
[UIView animateWithDuration:0.25
animations:^{
viewIsAnimating = YES;
} completion:^(BOOL finished) {
if (finished) {
viewIsAnimating = NO;
}
}];
回答6:
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.
回答7:
Ref to the question: UIView center position during animation
I compare the view's frame and layer.presentation()?.frame to check it is animating. If leftView is on the way to finish, the leftView.layer.presentation()?.frame does not equal to its frame:
if self.leftView.layer.presentation()?.frame == self.leftView.frame {
// the animation finished
} else {
// the animation on the way
}
But this method may not work if the view move to the end position during the animation. More condition check may be necessary.
回答8:
You could query the presentation layer as suggested here My presentation layer does not match my model layer even though I have no animations