测试 UIView 是否处于动画中间

发布于 2024-10-29 18:08:53 字数 552 浏览 0 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

凉墨 2024-11-05 18:08:53

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

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

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.

老旧海报 2024-11-05 18:08:53

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

let isInTheMiddleOfAnimation = UIView.inheritedAnimationDuration > 0

来自文档:

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

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.

谁人与我共长歌 2024-11-05 18:08:53

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

所以我认为你可以检查myView.layer.animationKeys

Animations are attached in fact to the underlying Core Animation CALayer class

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

怕倦 2024-11-05 18:08:53

这里有很多过时的答案。我只需要防止 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
}

这似乎比使用状态变量跟踪它更脆弱。

There are a lot of out-of-date answers here. I just needed to prevent a UIView animation being started if there was one running on the same view, so I created a category on 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.

傻比既视感 2024-11-05 18:08:53

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

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.

岁吢 2024-11-05 18:08:53

动画键技巧有一个问题。

有时,动画完成后可能会有一些动画键徘徊。

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

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

例如,

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

如果您对应用于图层的所有动画执行此操作,它将确保当图层没有动画时不存在任何动画键。

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.

廻憶裏菂餘溫 2024-11-05 18:08:53

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

我所做的是定义一个属性

@property BOOL viewIsAnimating;

并在我的动画中

[UIView animateWithDuration:0.25
                 animations:^{
                     viewIsAnimating = YES;
                 } completion:^(BOOL finished) {
                     if (finished) {
                         viewIsAnimating = NO;
                     }
                 }];

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;
                     }
                 }];
初懵 2024-11-05 18:08:53

参考问题: 动画期间的 UIView 中心位置

我比较视图的框架和图层。 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
}

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

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.

锦上情书 2024-11-05 18:08:53

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

if (view.layer.animationKeys.count) {

  // Animating

}else {

// No

}

在文档中:

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

返回包含当前所有动画的键的数组*
连接到接收器。数组的顺序与 * 的顺序一致
将在其中应用动画。

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文