简体   繁体   中英

How to restart CALayer animation while it is in progress?

I used this scenario with UIView's animations with no problems, but can't get it working with CALayer animation.

I have made a playground to demonstrate the problem:

import UIKit
import PlaygroundSupport

class EventHandler {
    @objc func onClick(_ button: UIButton) {

        button.layer.removeAllAnimations()

        button.layer.borderColor = UIColor.red.cgColor
        print("RED")

        CATransaction.begin()
        CATransaction.setCompletionBlock({
            button.layer.borderColor = UIColor.black.cgColor
            print("BLACK")
        })

        let colorAnimation = CABasicAnimation()
        colorAnimation.toValue = UIColor.black.cgColor
        colorAnimation.duration = 5
        button.layer.add(colorAnimation, forKey: "borderColor")
        CATransaction.commit()

    }
}

let eventHandler = EventHandler()

let button = UIButton(frame: CGRect.init(x: 0, y: 0, width: 200, height: 200))

button.backgroundColor = UIColor.gray
button.layer.borderColor = UIColor.black.cgColor
button.layer.borderWidth = 20
button.addTarget(eventHandler, action: #selector(EventHandler.onClick(_:)), for: .touchDown)

PlaygroundPage.current.liveView = button

What I want is when I click the button in the middle of animation, the animation should start over. But it seems like when I call removeAllAnimations() the completion block of the original animation is executed not before I set color to RED but after it.

Fixed the problem by setting fromValue to the animation object. Here is working version:

import UIKit
import PlaygroundSupport

class EventHandler {
    @objc func onClick(_ button: UIButton) {

        button.layer.removeAllAnimations()

        let colorAnimation = CABasicAnimation()
        colorAnimation.fromValue = UIColor.red.cgColor
        colorAnimation.toValue = UIColor.black.cgColor
        colorAnimation.duration = 5
        button.layer.add(colorAnimation, forKey: "borderColor")   
    }
}

let eventHandler = EventHandler()

let button = UIButton(frame: CGRect.init(x: 0, y: 0, width: 200, height: 200))

button.backgroundColor = UIColor.gray
button.layer.borderColor = UIColor.black.cgColor
button.layer.borderWidth = 20
button.addTarget(eventHandler, action: #selector(EventHandler.onClick(_:)), for: .touchDown)

PlaygroundPage.current.liveView = button

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM