核心动画-修改动画属性 [英] Core Animation - modify animation property

查看:63
本文介绍了核心动画-修改动画属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有动画

 func startRotate360() {
    let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
    rotation.fromValue = 0
    rotation.toValue =  Double.pi * 2
    rotation.duration = 1
    rotation.isCumulative = true
    rotation.repeatCount = Float.greatestFiniteMagnitude
    self.layer.add(rotation, forKey: "rotationAnimation")
}

我想要的是通过将其重复计数设置为1来停止动画的功能,因此它可以完成当前的旋转(仅删除动画是不可行的,因为它看起来不太好)

What I want is ability to stop animation by setting its repeat count to 1, so it completes current rotation (simply remove animation is not ok because it looks not good)

我尝试关注

func stopRotate360() {
    self.layer.animation(forKey: "rotationAnimation")?.repeatCount = 1
}

但是我崩溃了,在控制台中

But I get crash and in console


试图修改只读动画

attempting to modify read-only animation

如何访问可写属性?

推荐答案

可以尝试一下。实际上,您可以更改正在进行的CAAnimation。有很多方法。这是最快/最简单的。您甚至可以完全停止动画并继续播放,而无需用户注意。

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.

您可以看到开始动画功能以及停止位置。开始动画看上去与您的动画相似,而停止动画从表示层中获取当前旋转,并创建一个动画进行旋转直到完成。我也将持续时间平滑化为基于当前旋转z完成到基于运行动画的完整旋转所需时间的百分比。然后,我删除具有重复计数的动画并添加新的动画。您可以看到视图平滑旋转到最终位置并停止。您会明白的。放入并运行它,看看您的想法。点击按钮开始并再次点击它以查看它完成旋转和停止。

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")

            }
        }
    }
}

结果:

这篇关于核心动画-修改动画属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆