连续动画调用不起作用

时间:2015-09-08 03:53:29

标签: ios swift animatewithduration

我有一个调用animateWithDuration代码的按钮,该代码淡化图像,淡化文本和文本。一个新的bg颜色,然后重置为正常。动画需要几秒钟才能完成并且效果很好。

但是!有一个问题:

有时在动画结束前会再次按下此按钮。当发生这种情况时,我希望当前的动画停止并重新开始。

研究解决方案无效

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

button.layer.removeAllAnimations()

这会删除动画,但新/第二个动画完全搞砸了。应该隐藏的图像不是,文本永远不会出现,颜色过渡都是错误的。发生了什么事!!!

//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

@Shripada建议我切换到关键帧以获得更易读的代码。下面的关键帧格式。它没有解决动画中断问题。如果你能用嵌套或关键帧格式解决问题,请发布它!

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

2 个答案:

答案 0 :(得分:2)

您应该使用连续动画的完成块来避免在这种嵌套中对动画进行排序。这不仅使其难以理解,而且还难以理解和解决您提到的问题。

有一个更好的选择,称为关键帧动画,你应该考虑使用它(从iOS 7开始提供)。

animateKeyFramesWithDuration:delay:options:animation:completion

参考documentation

您的动画代码可以使用关键帧重写(PS:我没有测试过这个,只需为你的参考键入它) -

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/

答案 1 :(得分:2)

我在您的print方法中添加了一些animateFinished行,以便查看正在进行的操作:

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

如果您允许动画运行完成,则会显示日志,如您所料:

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

但是如果你在动画期间点击按钮,你会看到:

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

removeAllAnimations导致完成块(第一次调用)执行后, 第二次调用的初始设置完成后发生了什么,但是之前进行第二次动画。因此,例如,按钮标题是""在第二部动画中。

修复相对简单:如果动画尚未完成,请不要执行完成块:

        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中移除动画,其中包含:

footerImg.layer.removeAllAnimations()

在方法开始时。