连续animation调用不起作用

我有一个button,调用animateWithDuration代码淡出图像,淡入淡出的文本和新的颜色,然后重置为正常。 animation需要几秒钟才能完成,效果很好。

然而! 有一个问题:

有时候这个button会在animation结束之前再次被按下。 发生这种情况时,我希望当前animation停止并重新开始。

研究解决scheme不工作

根据我的阅读,解决scheme应该是简单的,只需导入QuartzCore并添加:

button.layer.removeAllAnimations() 

这确实删除了animation,但新的/第二个animation是完全搞砸了。 应该隐藏的图像不是,文本从不出现,颜色转换全部错误。 发生了什么!?!

 //Animate Finished feedback in footer bar func animateFinished(textToDisplay: String, footerBtn: UIButton, footerImg: UIImageView) { //Should cancel any current animation footerBtn.layer.removeAllAnimations() footerBtn.alpha = 0 footerBtn.setTitle(textToDisplay, forState: UIControlState.Normal) footerBtn.titleLabel!.font = UIFont(name: "HelveticaNeue-Regular", size: 18) footerBtn.setTitleColor(UIColor(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: 1.0), forState: UIControlState.Normal) footerBtn.backgroundColor = UIColor(red: 217/255.0, green: 217/255.0, blue: 217/255.0, alpha: 1.0) UIView.animateWithDuration(0.5, delay: 0.0, options: nil, animations: { footerImg.alpha = 0.01 //Img fades out footerBtn.backgroundColor = UIColor(red: 46/255.0, green: 163/255.0, blue: 00/255.0, alpha: 0.6) } , completion: { finished in UIView.animateWithDuration(0.5, delay: 0.0, options: nil, animations: { footerBtn.alpha = 1 //Text fades in footerBtn.backgroundColor = UIColor(red: 46/255.0, green: 208/255.0, blue: 11/255.0, alpha: 0.6) } , completion: { finished in UIView.animateWithDuration(0.5, delay: 1.0, options: nil, animations: { footerBtn.alpha = 0.01 //Text fades out footerBtn.backgroundColor = UIColor(red: 46/255.0, green: 173/255.0, blue: 00/255.0, alpha: 0.6) } , completion: { finished in UIView.animateWithDuration(0.5, delay: 0.0, options: nil, animations: { footerImg.alpha = 1 //Img fades in } , completion: { finished in footerBtn.backgroundColor = UIColor.clearColor() footerBtn.setTitleColor(UIColor(red: 55/255.0, green: 55/255.0, blue: 55/255.0, alpha: 1.0), forState: UIControlState.Normal) footerBtn.titleLabel!.font = UIFont(name: "HelveticaNeue-Light", size: 18) footerBtn.setTitle("", forState: UIControlState.Normal) footerBtn.alpha = 1 //Completion blocks sets values back to norm }) }) }) }) }//End of animation 

@Shripadabuild议我切换到关键帧以获取更多可读代码。 下面的关键帧格式。 它没有解决animation中断问题。 如果你能解决嵌套或关键帧格式的问题,请发布!

 func animateFinished(textToDisplay: String, footerBtn: UIButton, footerImg: UIImageView) { //Should cancel any current animation footerBtn.layer.removeAllAnimations() footerBtn.alpha = 0 footerBtn.setTitle(textToDisplay, forState: UIControlState.Normal) footerBtn.titleLabel!.font = UIFont(name: "HelveticaNeue-Regular", size: 18) footerBtn.setTitleColor(UIColor(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: 1.0), forState: UIControlState.Normal) //footerBtn.backgroundColor = UIColor(red: 217/255.0, green: 217/255.0, blue: 217/255.0, alpha: 1.0) UIView.animateKeyframesWithDuration(3.0 /*Total*/, delay:0.0, options: UIViewKeyframeAnimationOptions.CalculationModeLinear, animations: { UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration:0.10, animations:{ footerImg.alpha = 0.01 //Img fades out footerBtn.backgroundColor = UIColor(red: 46/255.0, green: 103/255.0, blue: 00/255.0, alpha: 0.6) //Bg turns to green }) UIView.addKeyframeWithRelativeStartTime(0.10, relativeDuration:0.30, animations:{ footerBtn.alpha = 1 //Text and green bg fades in footerBtn.backgroundColor = UIColor(red: 46/255.0, green: 173/255.0, blue: 11/255.0, alpha: 0.6) //BG turns greener }) UIView.addKeyframeWithRelativeStartTime(0.40, relativeDuration:0.50, animations:{ footerBtn.alpha = 0.01 //Text fades out & bg fade out }) }, completion: { finished in footerImg.alpha = 1 footerBtn.alpha = 1 footerBtn.backgroundColor = UIColor.clearColor() footerBtn.setTitleColor(UIColor(red: 55/255.0, green: 55/255.0, blue: 55/255.0, alpha: 1.0), forState: UIControlState.Normal) footerBtn.titleLabel!.font = UIFont(name: "HelveticaNeue-Light", size: 18) footerBtn.setTitle("", forState: UIControlState.Normal) //Completion blocks sets values back to norm } ) }//End of 'Finished' animation 

我为你的animateFinished方法添加了一些print行,以便看看发生了什么:

 func animateFinished(textToDisplay: String, footerBtn: UIButton, footerImg: UIImageView) { //Should cancel any current animation print("Remove animations") footerBtn.layer.removeAllAnimations() print("Animations removed") footerBtn.alpha = 0 footerBtn.setTitle(textToDisplay, forState: UIControlState.Normal) footerBtn.titleLabel!.font = UIFont(name: "HelveticaNeue-Regular", size: 18) footerBtn.setTitleColor(UIColor(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: 1.0), forState: UIControlState.Normal) //footerBtn.backgroundColor = UIColor(red: 217/255.0, green: 217/255.0, blue: 217/255.0, alpha: 1.0) print("Initial animation setup completed") UIView.animateKeyframesWithDuration(3.0 /*Total*/, delay:0.0, options: UIViewKeyframeAnimationOptions.CalculationModeLinear, animations: { UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration:0.10, animations:{ footerImg.alpha = 0.01 //Img fades out footerBtn.backgroundColor = UIColor(red: 46/255.0, green: 103/255.0, blue: 00/255.0, alpha: 0.6) //Bg turns to green }) UIView.addKeyframeWithRelativeStartTime(0.10, relativeDuration:0.30, animations:{ footerBtn.alpha = 1 //Text and green bg fades in footerBtn.backgroundColor = UIColor(red: 46/255.0, green: 173/255.0, blue: 11/255.0, alpha: 0.6) //BG turns greener }) UIView.addKeyframeWithRelativeStartTime(0.40, relativeDuration:0.50, animations:{ footerBtn.alpha = 0.01 //Text fades out & bg fade out }) }, completion: { finished in print("Completion block started") footerImg.alpha = 1 footerBtn.alpha = 1 footerBtn.backgroundColor = UIColor.clearColor() footerBtn.setTitleColor(UIColor(red: 55/255.0, green: 55/255.0, blue: 55/255.0, alpha: 1.0), forState: UIControlState.Normal) footerBtn.titleLabel!.font = UIFont(name: "HelveticaNeue-Light", size: 18) footerBtn.setTitle("", forState: UIControlState.Normal) //Completion blocks sets values back to norm print("Completion block finished") } ) }//End of 'Finished' animation 

如果您允许animation运行完成,日志会显示如您所期望的那样:

 Remove animations Animations removed Initial animation setup completed Completion block started Completion block finished 

但是,如果在animation过程中点击button,您会看到:

 Remove animations Animations removed Initial animation setup completed Remove animations Animations removed Initial animation setup completed Completion block started Completion block finished Completion block started Completion block finished 

在第二次调用的初始设置完成之后, 执行第二次animation之前removeAllAnimations会导致完成块(用于第一次调用)被执行。 所以,例如,第二个animation中的button标题是“”。

修复相对简单:如果animation未完成,则不要执行完成块:

  completion: { finished in if (!finished) { return } print("Completion block started") footerImg.alpha = 1 footerBtn.alpha = 1 footerBtn.backgroundColor = UIColor.clearColor() footerBtn.setTitleColor(UIColor(red: 55/255.0, green: 55/255.0, blue: 55/255.0, alpha: 1.0), forState: UIControlState.Normal) footerBtn.titleLabel!.font = UIFont(name: "HelveticaNeue-Light", size: 18) footerBtn.setTitle("", forState: UIControlState.Normal) print("Completion block finished") //Completion blocks sets values back to norm } 

此外,根据Shripada,您将需要从footerImg以及footerBtn中删除animation:

 footerImg.layer.removeAllAnimations() 

在方法的开始。

您应该避免使用连续animation的完成块在这种嵌套中sortinganimation。 这不仅使得它难以理解,而且难以理解和解决你所提到的问题。

有一个更好的select,称为关键帧animation,你应该考虑使用它(可用iOS 7以上)。

 animateKeyFramesWithDuration:delay:options:animation:completion 

参考文档

您的animation代码可以使用关键帧来重写(PS:我没有testing过这个,只需input你的参考)

 func animateFinished(textToDisplay: String, footerBtn: UIButton, footerImg: UIImageView) { //Should cancel any current animation footerBtn.layer.removeAllAnimations() footerImg.layer.removeAllAnimations() footerBtn.alpha = 0 footerBtn.setTitle(textToDisplay, forState: UIControlState.Normal) footerBtn.titleLabel!.font = UIFont(name: "HelveticaNeue-Regular", size: 18) footerBtn.setTitleColor(UIColor(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: 1.0), forState: UIControlState.Normal) //footerBtn.backgroundColor = UIColor(red: 217/255.0, green: 217/255.0, blue: 217/255.0, alpha: 1.0) UIView.animateKeyframesWithDuration(3.0 /*Total*/, delay:0.0, options: UIViewKeyframeAnimationOptions.CalculationModeLinear, animations: { UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration:0.10, animations:{ footerImg.alpha = 0.01 //Img fades out footerBtn.backgroundColor = UIColor(red: 46/255.0, green: 103/255.0, blue: 00/255.0, alpha: 0.6) //Bg turns to green }) UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration:0.30, animations:{ footerBtn.alpha = 1 //Text and green bg fades in footerBtn.backgroundColor = UIColor(red: 46/255.0, green: 173/255.0, blue: 11/255.0, alpha: 0.6) //BG turns greener }) UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration:0.50, animations:{ footerBtn.alpha = 0.01 //Text fades out & bg fade out }) }, completion: { finished in footerImg.alpha = 1 footerBtn.alpha = 1 footerBtn.backgroundColor = UIColor.clearColor() footerBtn.setTitleColor(UIColor(red: 55/255.0, green: 55/255.0, blue: 55/255.0, alpha: 1.0), forState: UIControlState.Normal) footerBtn.titleLabel!.font = UIFont(name: "HelveticaNeue-Light", size: 18) footerBtn.setTitle("", forState: UIControlState.Normal) //Completion blocks sets values back to norm } ) }//End of 'Finished' animation 

也请参阅这个链接,虽然它是obj c,非常丰富。 http://www.raizlabs.com/dev/2015/01/uiview-animation-sequencing-and-grouping-techniques/

Interesting Posts