ios 触发新动画时如何取消之前的动画?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28317564/
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
How to cancel previous animation when a new one is triggered?
提问by HanXu
I am writing a camera app, and have trouble with showing the focus square when user tap on the screen.
我正在编写一个相机应用程序,当用户点击屏幕时无法显示焦点方块。
My code is (in swift):
我的代码是(迅速):
self.focusView.center = sender.locationInView(self.cameraWrapper)
self.focusView.transform = CGAffineTransformMakeScale(2, 2)
self.focusView.hidden = false
UIView.animateWithDuration(0.5, animations: { [unowned self] () -> Void in
self.focusView.transform = CGAffineTransformIdentity
}, completion: { (finished) -> Void in
UIView.animateWithDuration(0.5, delay: 1.0, options: nil, animations: { () -> Void in
self.focusView.alpha = 0.0
}, completion: { (finished) -> Void in
self.focusView.hidden = true
self.focusView.alpha = 1.0
})
})
However, if use tap the screen consecutively when the previous animation does not finish, the old and new animation will mix up and the focus view will behave strangely, for example it will disappear very quick.
但是,如果在前一个动画没有完成时连续点击屏幕,新旧动画会混淆,焦点视图会表现得很奇怪,例如它会很快消失。
Could anyone tell me how to cancel previous animation, especially the previous completion block?
谁能告诉我如何取消之前的动画,尤其是之前的完成块?
回答by Jageen
You can user method removeAllAnimations
to stop animation
Replace your code with below
您可以使用removeAllAnimations
停止动画的方法
用下面的代码替换您的代码
self.focusView.center = sender.locationInView(self.cameraWrapper)
self.focusView.transform = CGAffineTransformMakeScale(2, 2)
self.focusView.hidden = false
self.focusView.layer.removeAllAnimations() // <<==== Solution
UIView.animateWithDuration(0.5, animations: { [unowned self] () -> Void in
self.focusView.transform = CGAffineTransformIdentity
}, completion: { (finished) -> Void in
UIView.animateWithDuration(0.5, delay: 1.0, options: nil, animations: { () -> Void in
self.focusView.alpha = 0.0
}, completion: { (finished) -> Void in
self.focusView.hidden = true
self.focusView.alpha = 1.0
})
})
Reference : link
参考:链接
回答by Ron
In my case, I add the focusing indicator by using addSubview()
.
就我而言,我使用addSubview()
.
self.view.addSubview(square)
square is the UIView I defined in the function. So when the user tap the screen to focus, this function will add a square on subview. And to cancel this animation when the next tap happen, I just simply use the removeFromSuperview() function, when this function called it removes the view from its superview which is the focusing square here.
square 是我在函数中定义的 UIView。所以当用户点击屏幕聚焦时,这个函数会在子视图上添加一个方块。为了在下一次点击发生时取消这个动画,我只是简单地使用 removeFromSuperview() 函数,当这个函数调用它时,它会从它的超级视图中删除视图,这是这里的聚焦方块。
filterView.subviews.forEach({ public func configureStackView(hideView1: Bool, hideView2: Bool) {
let oldHideView1 = view1.isHidden
let oldHideView2 = view2.isHidden
view1.layer.removeAllAnimations()
view2.layer.removeAllAnimations()
view.layer.removeAllAnimations()
stackView.layer.removeAllAnimations()
// after stopping animation the values are unpredictable, so set values to old
view1.isHidden = oldHideView1 // <- Solution is here
view2.isHidden = oldHideView2 // <- Solution is here
UIView.animate(withDuration: 0.3,
delay: 0.0,
usingSpringWithDamping: 0.9,
initialSpringVelocity: 1,
options: [],
animations: {
view1.isHidden = hideView1
view2.isHidden = hideView2
stackView.layoutIfNeeded()
},
completion: nil)
}
.removeFromSuperview() })
It's different from the method above to remove the animation, but remove the subview directly.
和上面的移除动画的方法不同,而是直接移除子视图。
回答by Paul T.
@Jageen solution is great, but I worked with UIStackView animation and there I needed additional steps. I have stackView with view1 and view2 inside, and one view should be visible and one hidden:
@Jageen 解决方案很棒,但我使用了 UIStackView 动画,在那里我需要额外的步骤。我有一个带有 view1 和 view2 的 stackView,一个视图应该是可见的,一个是隐藏的:
if ([indexPath isEqual:self.currentPlayerOrderIndexPath])
{
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut
animations:^{
cell.avatarImageV.transform = CGAffineTransformMakeScale(1.15,1.15);
}
completion:NULL];
}
else
{
cell.avatarImageV.transform = CGAffineTransformMakeScale(1.0, 1.0);
回答by Nik Kov
In my case, i just needed to set the value, i animated to concrete value.
在我的情况下,我只需要设置值,我将动画设置为具体值。
For e.g.
例如
##代码##