56

有什么方法可以判断 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>>

当动画停止并打印视图时,“动画”条目现在消失了:

search bar should end editing: <UISearchBar: 0x2e6240; frame = (0 0; 320 88); text = ''; autoresize = W+BM; layer = <CALayer: 0x2e6e00>>
4

10 回答 10

43

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

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

于 2011-04-02T23:23:18.580 回答
26

iOS 9+ 方法,即使layer.animationKeys不包含键也可以工作:

let isInTheMiddleOfAnimation = UIView.inheritedAnimationDuration > 0

从文档:

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

于 2018-01-26T14:18:29.827 回答
25

动画实际上附加到底层的核心动画CALayer

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

于 2011-04-02T23:21:29.510 回答
10

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.

于 2012-05-21T14:46:42.240 回答
10

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

extension UIView {

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

}

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

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

这似乎不如使用状态变量跟踪它那么脆弱。

于 2019-10-24T14:58:26.083 回答
5

animationKeys 技巧有一个障碍。

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

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

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

例如

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"aPath"];
animation.removedOnCompletion = YES;

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

于 2012-02-20T07:03:21.567 回答
3

其中一些对我不起作用。原因是这些动画是异步的。

我所做的是定义了一个属性

@property BOOL viewIsAnimating;

在我的动画中

[UIView animateWithDuration:0.25
                 animations:^{
                     viewIsAnimating = YES;
                 } completion:^(BOOL finished) {
                     if (finished) {
                         viewIsAnimating = NO;
                     }
                 }];
于 2015-08-21T02:20:12.630 回答
1

参考问题:UIView center position during animation

我比较了视图的 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
}

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

于 2018-03-29T08:32:41.863 回答
0

您可以按照此处的建议查询表示层我的表示层与我的模型层不匹配,即使我没有动画

于 2011-04-03T07:18:59.983 回答
0

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

if (view.layer.animationKeys.count) {

  // Animating

}else {

// No

}

在文档中:

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

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

于 2019-05-24T12:37:25.720 回答