本文介绍了连续动画调用不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a button that calls an animateWithDuration code that fades an image out, fades text & a new bg color in , and then resets back to normal. The animation takes a few seconds to complete and works great.

然而!有一个问题:

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

Sometimes this button will be pushed again before the animation finishes. When this happens, I want the current animate to stop and start over again.

研究解决方案无法正常工作

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

According to my reading, the solution should be simple, just import QuartzCore and add:

button.layer.removeAllAnimations()

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

This does remove the animation but the new/second animation is totally messed up. The image that is supposed to be hidden isn't, the text never shows up, and the color transition is all wrong. What's happening!?!

//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建议我切换到关键帧以获得更易读的代码。下面的关键帧格式。它没有解决动画中断问题。如果您可以用嵌套或关键帧格式解决问题,请发布!

@Shripada suggested I switch to keyframes for more readable code. Keyframe format below. It did not solve the animation interruption problem. If you can solve the problem in nested or keyframe format, please post it!

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 行,为了看看发生了什么:

I added some print lines to your animateFinished method, in order to see what's going on:

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

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

If you allow the animations to run to completion, the log shows, as you would expect:

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

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

But if you tap the button during the animation, you see this:

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 导致完成块(对于第一次调用)要执行,第二次调用的初始设置完成后,之前进行第二次动画。因此,例如,在第二个动画期间按钮标题为。

What's happening it that the removeAllAnimations causes the completion block (for the first call) to be executed, after the initial setup for the second call is completed, but before the second animations are undertaken. So, for example, the button title is "" during the second animation.

修复相对简单:如果动画没有,则不执行完成块完成:

The fix is relatively straight forward: don't execute the completion block if the animations have not finished:

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

Also, as per Shripada, you will need to remove animations from footerImg as well as footerBtn, with:

footerImg.layer.removeAllAnimations()

在方法开头。

这篇关于连续动画调用不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 11:30