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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 04:40:02  来源:igfitidea点击:

How to cancel previous animation when a new one is triggered?

iosswift

提问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 removeAllAnimationsto 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
enter image description here


参考:链接
在此处输入图片说明

回答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.

例如

##代码##