ios 测试 UIView 是否处于动画中间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5526476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:25:58  来源:igfitidea点击:

Test whether a UIView is in the middle of animation

ioscocoa-touchuiviewcore-animationuiviewanimation

提问by prostock

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:

有没有办法判断 UIView 是否在动画中间?当我在移动时打印出视图对象时,我注意到有一个“动画”条目:

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>>

采纳答案by Nick Weaver

A UIViewhas a layer (CALayer). You can send animationKeysto 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 CAMediaTimingprotocolwhich CALayeradopts. It does some more information on the current animation.

AUIView有一个层 ( CALayer)。您可以发送animationKeys给它,它将为您提供一组键,用于标识附加到图层的动画。我想如果有任何条目,动画正在运行。如果你想挖更深看看的CAMediaTiming协议,其CALayer采用。它提供有关当前动画的更多信息。

Important: If you add an animation with a nilkey ([layer addAnimation:animation forKey:nil]), animationKeysreturns nil.

重要提示:如果您添加带有nil键 ( [layer addAnimation:animation forKey:nil])的动画,则animationKeys返回nil.

回答by Vincent Guerci

Animations are attached in fact to the underlying Core Animation CALayerclass

动画实际上附加到底层的 Core AnimationCALayer

So I think you can just check myView.layer.animationKeys

所以我想你可以检查一下 myView.layer.animationKeys

回答by deej

iOS 9+ method, works even when layer.animationKeyscontains no keys:

iOS 9+ 方法,即使layer.animationKeys不包含任何键也能工作:

let isInTheMiddleOfAnimation = UIView.inheritedAnimationDuration > 0

From the docs:

从文档:

This method only returns a non-zero value if called within a UIView animation block.

如果在 UIView 动画块中调用此方法,则仅返回非零值。

回答by Ryan Poolos

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 UIViewAnimationOptionBeginFromCurrentStatethat will combine the animations if necessary to give a smooth appearance. Thereby eliminating my need to know if the view was animating.

我不确定问题的上下文,但我试图在开始第二个动画之前找出视图是否正在动画以避免跳过。但是,有一个 UIView 动画选项UIViewAnimationOptionBeginFromCurrentState可以在必要时组合动画以提供平滑的外观。从而消除了我需要知道视图是否在动画中的需要。

回答by C4 - Travis

There is a hitch with the animationKeys trick.

animationKeys 技巧有一个问题。

Sometimes there could be a few animationKeys lingering after an animation is completed.

有时在动画完成后可能会有一些 animationKeys 挥之不去。

This means that a non-animating layer could return a set of animationKeys even if it isn't actually animating.

这意味着,非动画层可以返回一组animationKeys,即使它实际上没有动画。

You can make sure that animationKeys are automatically removed by setting an animation's removedOnCompletion property to YES.

您可以通过将动画的 removedOnCompletion 属性设置为 YES 来确保自动删除 animationKeys。

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.

如果对应用于图层的所有动画执行此操作,将确保当图层未设置动画时不存在 animationKeys。

回答by MendyK

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;
                     }
                 }];

回答by Echelon

There are a lot of out-of-date answers here. I just needed to prevent a UIViewanimation being started if there was one running on the same view, so I created a category on UIView:-

这里有很多过时的答案。UIView如果在同一个视图上运行一个动画,我只需要防止启动动画,所以我创建了一个类别UIView:-

extension UIView {

    var isAnimating: Bool {
        return (self.layer.animationKeys()?.count ?? 0) > 0
    }

}

This way I can just check any view's animation status like this:-

这样我就可以像这样检查任何视图的动画状态:-

if !myView.isAnimating {
  UIView.animate(withDuration: 0.4) {
    ...
  }
} else {
  // already animating
}

This seems less fragile than keeping track of it with a state variable.

这似乎没有用状态变量跟踪它那么脆弱。

回答by Bill Chan

Ref to the question: UIView center position during animation

参考问题: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:

我比较视图的框架和 layer.presentation()?.frame 以检查它是否具有动画效果。如果 leftView 在完成的路上, leftView.layer.presentation()?.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.

但是如果视图在动画过程中移动到结束位置,则此方法可能不起作用。可能需要更多的条件检查。

回答by varunrathi28

You can use the layer property of a UIView. CALayer has a property called animation keys, you can check its count if it is greater than 0.

您可以使用 UIView 的图层属性。CALayer 有一个叫做动画键的属性,你可以检查它的计数是否大于 0。

if (view.layer.animationKeys.count) {

  // Animating

}else {

// No

}

In the Documentation:

在文档中:

-(nullable NSArray<NSString *> *)animationKeys;

Returns an array containing the keys of all animations currently * attached to the receiver. The order of the array matches the order * in which animations will be applied.

返回一个数组,其中包含当前附加到接收器的所有动画的键。数组的顺序与应用动画的顺序 * 相匹配。

回答by HeikoG