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
Test whether a UIView is in the middle of animation
提问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 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
protocolwhich CALayer
adopts. It does some more information on the current animation.
AUIView
有一个层 ( CALayer
)。您可以发送animationKeys
给它,它将为您提供一组键,用于标识附加到图层的动画。我想如果有任何条目,动画正在运行。如果你想挖更深看看的CAMediaTiming
协议,其CALayer
采用。它提供有关当前动画的更多信息。
Important: If you add an animation with a nil
key ([layer addAnimation:animation forKey:nil]
), animationKeys
returns nil
.
重要提示:如果您添加带有nil
键 ( [layer addAnimation:animation forKey:nil]
)的动画,则animationKeys
返回nil
.
回答by Vincent Guerci
Animations are attached in fact to the underlying Core Animation CALayer
class
动画实际上附加到底层的 Core AnimationCALayer
类
So I think you can just check myView.layer.animationKeys
所以我想你可以检查一下 myView.layer.animationKeys
回答by deej
iOS 9+ method, works even when layer.animationKeys
contains 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 UIViewAnimationOptionBeginFromCurrentState
that 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 UIView
animation 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
You could query the presentation layer as suggested here My presentation layer does not match my model layer even though I have no animations
您可以按照此处的建议查询表示层即使我没有动画,我的表示层也不匹配我的模型层