Ana
Ana

Reputation: 119

Stop old animation and start new one, once I change segments, swift

Is there a method or function that can stop previous animation, when I switch segment controls? If I don't remove animation, image that was fading on first segment, starts rotating on the second and then moves on the third segment. While I switch segments, it works more like appending different animations all the time.

I tried: - removeAllAnimations(), but it doesn't work properly. - self.view.layer.removeAnimation(forKey: "moveAnimation"). Tried that one at the end of the code for each segment choice.

Maybe I am not putting it in the right spot, but I can't get it working properly

Here is my code:

import UIKit

class MoveViewController: UIViewController {


    @IBOutlet var sgAction : UISegmentedControl!

    var moveLayer : CALayer?

    @IBAction func segmentDidChange(sender : UISegmentedControl){
        updateAction()

    }


    func updateAction(){
        let action = sgAction.selectedSegmentIndex

        if action == 0 {
            //fade

            let fadeAnimation = CABasicAnimation(keyPath: "opacity")

            self.view.layer.removeAnimation(forKey: "fadeAnimation")

            fadeAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
            fadeAnimation.fromValue = NSNumber.init(value: 1.0)
            fadeAnimation.toValue = NSNumber.init(value: 0.0)
            fadeAnimation.isRemovedOnCompletion = false

            fadeAnimation.duration = 3.0
            fadeAnimation.beginTime = 1.0
            fadeAnimation.isAdditive = false
            fadeAnimation.fillMode = CAMediaTimingFillMode.both
            fadeAnimation.repeatCount = Float.infinity
            moveLayer?.add(fadeAnimation, forKey: nil)

        } else if action == 1 {
            //2. rotate

            let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")

            self.view.layer.removeAnimation(forKey: "rotateAnimation")

            rotateAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
            rotateAnimation.fromValue = 0
            rotateAnimation.toValue = 2 * Double.pi

            rotateAnimation.isRemovedOnCompletion = false

            rotateAnimation.duration = 1.0
            rotateAnimation.repeatCount = Float.infinity
            moveLayer?.add(rotateAnimation, forKey:nil)


        } else {
            //3. move

            let moveAnimation = CABasicAnimation(keyPath: "position")
            self.view.layer.removeAnimation(forKey: "moveAnimation")

            moveAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)

            moveAnimation.fromValue = NSValue.init(cgPoint: CGPoint(x: 0, y: 0))
            moveAnimation.toValue = NSValue.init(cgPoint: CGPoint(x: 700, y: 500))
            moveAnimation.isRemovedOnCompletion = false
            moveAnimation.duration = 3.0
            moveAnimation.repeatCount = Float.infinity
            moveLayer?.add(moveAnimation, forKey: nil)

        }
    }
//        moveLayer?.removeAllAnimations()




    func createImg(){
        let displayImage = UIImage(named: "balloon.png")
        moveLayer = CALayer.init()
        moveLayer?.contents = displayImage?.cgImage
        moveLayer?.bounds = CGRect(x: 0, y: 0, width: 150, height: 150)
        moveLayer?.position = CGPoint(x: 300, y: 200)
        self.view.layer.addSublayer(moveLayer!)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        createImg()
//      moveLayer?.removeAllAnimations()
        updateAction()

    }

}

Upvotes: 0

Views: 264

Answers (1)

MwcsMac
MwcsMac

Reputation: 7168

When you add moveLayer?.removeAllAnimations() and self.moveLayer.layoutIfNeed() to the segmentDidChange(sender : UISegmentedControl). Also the other key item that needs to get changed is moveLayer?.add(fadeAnimation, forKey: "nil") to moveLayer?.add(fadeAnimation, forKey: "fadeAnimation").

import UIKit

class MoveViewController: UIViewController {

    @IBOutlet var sgAction : UISegmentedControl!

    var moveLayer : CALayer?

    override func viewDidLoad() {
        super.viewDidLoad()
        createImg()
        updateAction()
    }

    @IBAction func segmentDidChange(sender : UISegmentedControl){
        moveLayer?.removeAllAnimations()
        self.moveLayer?.layoutIfNeeded()
        updateAction()
    }

    func updateAction(){
        switch sgAction.selectedSegmentIndex {
        case 0:
            //fade
            let fadeAnimation = CABasicAnimation(keyPath: "opacity")

            fadeAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
            fadeAnimation.fromValue = NSNumber.init(value: 1.0)
            fadeAnimation.toValue = NSNumber.init(value: 0.0)
            fadeAnimation.isRemovedOnCompletion = false

            fadeAnimation.duration = 3.0
            fadeAnimation.beginTime = 1.0
            fadeAnimation.isAdditive = false
            fadeAnimation.fillMode = CAMediaTimingFillMode.both
            fadeAnimation.repeatCount = Float.infinity
            moveLayer?.add(fadeAnimation, forKey: "fadeAnimation")

        case 1:
            //2. rotate
            let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")

            rotateAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
            rotateAnimation.fromValue = 0
            rotateAnimation.toValue = 2 * Double.pi

            rotateAnimation.isRemovedOnCompletion = false

            rotateAnimation.duration = 1.0
            rotateAnimation.repeatCount = Float.infinity
            moveLayer?.add(rotateAnimation, forKey: "rotateAnimation")

        case 2:
            //3. move
            let moveAnimation = CABasicAnimation(keyPath: "position")

            moveAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)

            moveAnimation.fromValue = NSValue.init(cgPoint: CGPoint(x: 0, y: 0))
            moveAnimation.toValue = NSValue.init(cgPoint: CGPoint(x: 700, y: 500))
            moveAnimation.isRemovedOnCompletion = false
            moveAnimation.duration = 3.0
            moveAnimation.repeatCount = Float.infinity
            moveLayer?.add(moveAnimation, forKey: "position")
        default: break

        }
    }

    func createImg(){
        let displayImage = UIImage(named: "balloon.png")
        moveLayer = CALayer.init()
        moveLayer?.contents = displayImage?.cgImage
        moveLayer?.bounds = CGRect(x: 0, y: 0, width: 150, height: 150)
        moveLayer?.position = CGPoint(x: 300, y: 200)
        self.view.layer.addSublayer(moveLayer!)
    }

}

Upvotes: 1

Related Questions