简体   繁体   中英

Add animation after removeAllAnimations doesn't work

I have simple application that is the red view transform position form left screen to right screen. I want when I hit remove button, the animation will be restart (the red view transform position form left screen to right screen again) but it doesn't works. The red view back to origin frame but it's not moving, but animationDidStop still called after duration.

class TestViewController: UIViewController, CAAnimationDelegate {

let testView : UIView = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .red
    view.layer.borderColor = UIColor.black.cgColor
    view.layer.cornerRadius = 5
    return view
}()

let removeAniButton : UIButton = {
    let btn = UIButton(type: .system)
    btn.translatesAutoresizingMaskIntoConstraints = false
    btn.setTitle("Remove", for: .normal)
    return btn
}()

let addAniButton : UIButton = {
    let btn = UIButton(type: .system)
    btn.translatesAutoresizingMaskIntoConstraints = false
    btn.setTitle("Add", for: .normal)
    return btn
}()

override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = .white

    view.addSubview(testView)
    testView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
    testView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
    testView.heightAnchor.constraint(equalToConstant: 100).isActive = true
    testView.widthAnchor.constraint(equalToConstant: 100).isActive = true

    view.addSubview(removeAniButton)
    removeAniButton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true
    removeAniButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
    removeAniButton.widthAnchor.constraint(equalToConstant: 100).isActive = true
    removeAniButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
    removeAniButton.addTarget(self, action: #selector(removeAnimation), for: .touchUpInside)

    view.addSubview(addAniButton)
    addAniButton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 150).isActive = true
    addAniButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
    addAniButton.widthAnchor.constraint(equalToConstant: 100).isActive = true
    addAniButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
    addAniButton.addTarget(self, action: #selector(addAnimation), for: .touchUpInside)

    addAnimation()
    // Do any additional setup after loading the view.
}

func createAnimation() -> CAAnimation {
    let animation = CABasicAnimation(keyPath: "position.x")
    animation.fromValue = 0
    animation.toValue = self.view.frame.width
    animation.duration = 4
    animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear) 
    animation.fillMode = kCAFillModeForwards
    animation.isRemovedOnCompletion = false
    animation.delegate = self
    return animation
}

func removeAnimation(){
    testView.layer.removeAllAnimations()
    testView.transform = .identity
    addAnimation()
}

func addAnimation(){
    testView.layer.add(createAnimation(), forKey: nil)
}

func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
    if flag {
        print("Animation is finished")
    }
  }
}

can anyone explain ?

Your problem is that you are using the wrong keyPath for your animation, If you want to reset your animation using testView.transform = .identity you need use transform.translation.x instead of "position.x" as animation keyPath, also is not needed call removeAllAnimations() only calling again your addAnimation will do the job

use this code for animation creation

func createAnimation() -> CAAnimation {
    let animation = CABasicAnimation(keyPath: "transform.translation.x")
    animation.fromValue = 0
    animation.toValue = self.view.frame.width
    animation.duration = 4
    animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear)
    animation.fillMode = kCAFillModeForwards
    animation.isRemovedOnCompletion = false
    return animation
}

func removeAnimation(){
    //customView.layer.removeAllAnimations()
    //customView.transform = .identity
    addAnimation()
}

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