Core Animation - modify animation property

后端 未结 3 912
没有蜡笔的小新
没有蜡笔的小新 2020-12-21 13:47

I have animation

 func startRotate360() {
    let rotation : CABasicAnimation = CABasicAnimation(keyPath: \"transform.rotation.z\")
    rotation.fromValue =          


        
3条回答
  •  醉梦人生
    2020-12-21 14:27

    Give this a go. You can in fact change CAAnimations that are in progress. There are so many ways. This is the fastest/simplest. You could even stop the animation completely and resume it without the user even noticing.

    You can see the start animation function along with the stop. The start animation looks similar to yours while the stop grabs the current rotation from the presentation layer and creates an animation to rotate until complete. I also smoothed out the duration to be a percentage of the time needed to complete based on current rotation z to full rotation based on the running animation. Then I remove the animation with the repeat count and add the new animation. You can see the view rotate smoothly to the final position and stop. You will get the idea. Drop it in and run it and see what you think. Hit the button to start and hit it again to see it finish rotation and stop.

    import UIKit
    
    class ViewController: UIViewController {
    
        var animationView = UIView()
        var button = UIButton()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
    
            animationView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
            animationView.backgroundColor = .green
            animationView.center = view.center
            self.view.addSubview(animationView)
    
            let label = UILabel(frame: animationView.bounds)
            label.text = "I Spin"
            animationView.addSubview(label)
    
    
            button = UIButton(frame: CGRect(x: 20, y: animationView.frame.maxY + 60, width: view.bounds.width - 40, height: 40))
            button.setTitle("Animate", for: .normal)
            button.setTitleColor(.blue, for: .normal)
            button.addTarget(self, action: #selector(ViewController.pressed), for: .touchUpInside)
            self.view.addSubview(button)
    
        }
    
        func pressed(){
    
            if let title = button.titleLabel?.text{
                let trans = CATransition()
                trans.type = "rippleEffect"
                trans.duration = 0.6
                button.layer.add(trans, forKey: nil)
    
                switch title {
                case "Animate":
                    //perform animation
                    button.setTitle("Stop And Finish", for: .normal)
                    rotateAnimationRepeat()
                    break
                default:
                    //stop and finish
                    button.setTitle("Animate", for: .normal)
                    stopAnimationAndFinish()
                    break
                }
            }
    
        }
    
        func rotateAnimationRepeat(){
            //just to be sure because of how i did the project
            animationView.layer.removeAllAnimations()
            let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
            rotation.fromValue = 0
            rotation.toValue =  Double.pi * 2
            rotation.duration = 0.5
            rotation.repeatCount = Float.greatestFiniteMagnitude
            //not doing cumlative
            animationView.layer.add(rotation, forKey: "rotationAnimation")
        }
    
        func stopAnimationAndFinish(){
            if let presentation = animationView.layer.presentation(){
                if let currentRotation = presentation.value(forKeyPath: "transform.rotation.z") as? CGFloat{
    
                    var duration = 0.5
    
                    //smooth out duration for change
                    duration = Double((CGFloat(Double.pi * 2) - currentRotation))/(Double.pi * 2)
                    animationView.layer.removeAllAnimations()
    
                    let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
                    rotation.fromValue = currentRotation
                    rotation.toValue = Double.pi * 2
                    rotation.duration = duration * 0.5
                    animationView.layer.add(rotation, forKey: "rotationAnimation")
    
                }
            }
        }
    }
    

    Result:

提交回复
热议问题