How to cancel previous animation when a new one is triggered?
You can user method removeAllAnimations
to stop animation
Replace your code with below
self.focusView.center = sender.locationInView(self.cameraWrapper)self.focusView.transform = CGAffineTransformMakeScale(2, 2)self.focusView.hidden = falseself.focusView.layer.removeAllAnimations() // <<==== SolutionUIView.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
@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:
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)}
In my case, I add the focusing indicator by using 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.
filterView.subviews.forEach({ $0.removeFromSuperview() })
It's different from the method above to remove the animation, but remove the subview directly.