我有动画
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 来停止动画,从而完成当前旋转(简单地删除动画是不行的,因为它看起来不太好)
我试着跟随
func stopRotate360() {
self.layer.animation(forKey: "rotationAnimation")?.repeatCount = 1
}
但是我崩溃了并且在控制台中
attempting to modify read-only animation
如何访问可写属性?
最佳答案
试一试。实际上,您可以更改正在进行的 CAAnimations。有很多方法。这是最快/最简单的。您甚至可以完全停止动画并在用户不注意的情况下继续播放。
您可以看到开始动画功能和停止功能。开始动画看起来与您的类似,而停止从表示层获取当前旋转并创建动画以旋转直到完成。我还将持续时间平滑为完成基于当前旋转 z 到基于运行动画的完整旋转所需时间的百分比。然后我删除带有重复计数的动画并添加新动画。您可以看到 View 平滑地旋转到最终位置并停止。你会明白的。将其放入并运行它,看看您的想法。点击按钮开始并再次点击以查看它完成旋转并停止。
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")
}
}
}
}
关于ios - 核心动画——修改动画属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45592182/