使用animateKeyframesWithDuration在屏幕上创build一个连续旋转的正方形

我试图用下面的代码在屏幕上创build一个连续旋转的正方形。 但我不知道为什么转速正在变化。 我怎样才能改变代码,使转速不变? 我尝试了不同的UIViewKeyframeAnimationOptions ,但似乎没有一个工作。

 override func viewDidLoad() { super.viewDidLoad() let square = UIView() square.frame = CGRect(x: 55, y: 300, width: 40, height: 40) square.backgroundColor = UIColor.redColor() self.view.addSubview(square) let duration = 1.0 let delay = 0.0 let options = UIViewKeyframeAnimationOptions.Repeat UIView.animateKeyframesWithDuration(duration, delay: delay, options: options, animations: { let fullRotation = CGFloat(M_PI * 2) UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1/3, animations: { square.transform = CGAffineTransformMakeRotation(1/3 * fullRotation) }) UIView.addKeyframeWithRelativeStartTime(1/3, relativeDuration: 1/3, animations: { square.transform = CGAffineTransformMakeRotation(2/3 * fullRotation) }) UIView.addKeyframeWithRelativeStartTime(2/3, relativeDuration: 1/3, animations: { square.transform = CGAffineTransformMakeRotation(3/3 * fullRotation) }) }, completion: {finished in }) } 

这真是奇怪的… UIView.animateKeyframesWithDuration不工作,因为我期望它与UIViewKeyframeAnimationOptions.CalculationModeLinear|UIViewKeyframeAnimationOpti‌​ons.Repeat与选项传入。

如果使用创build关键帧animation的非块方法(请参见下文),则旋转会按预期重复。

如果我发现为什么基于块的选项不起作用,我会尽量记住在这里更新答案!

 override func viewDidLoad() { super.viewDidLoad() let square = UIView() square.frame = CGRect(x: 55, y: 300, width: 40, height: 40) square.backgroundColor = UIColor.redColor() self.view.addSubview(square) let fullRotation = CGFloat(M_PI * 2) let animation = CAKeyframeAnimation() animation.keyPath = "transform.rotation.z" animation.duration = 2 animation.removedOnCompletion = false animation.fillMode = kCAFillModeForwards animation.repeatCount = Float.infinity animation.values = [fullRotation/4, fullRotation/2, fullRotation*3/4, fullRotation] square.layer.addAnimation(animation, forKey: "rotate") } 

我面临同样的问题之前,这是我如何使其工作:

 let raw = UIViewKeyframeAnimationOptions.Repeat.rawValue | UIViewAnimationOptions.CurveLinear.rawValue let options = UIViewKeyframeAnimationOptions(rawValue: raw) 

在放弃之前,我想到了这个问题。 我不认为有关于它的文件,但它只是工作。

添加UIViewKeyframeAnimationOptionCalculationModeLinear做你的关键帧选项。 UIViewanimation的默认行为是“放松/缩小”animation。 即开始缓慢,加快速度,然后在接近结束时再次减速。

AFAIU,这是因为默认的animation曲线是UIViewAnimationOption.CurveEaseInOut

不幸的是, UIViewKeyframeAnimationOptions没有改变曲线的选项,但你可以手动添加它们!

使用这个扩展名:

 extension UIViewKeyframeAnimationOptions { static var CurveEaseInOut: UIViewKeyframeAnimationOptions { return UIViewKeyframeAnimationOptions(rawValue: UIViewAnimationOptions.CurveEaseInOut.rawValue) } static var CurveEaseIn: UIViewKeyframeAnimationOptions { return UIViewKeyframeAnimationOptions(rawValue: UIViewAnimationOptions.CurveEaseIn.rawValue) } static var CurveEaseOut: UIViewKeyframeAnimationOptions { return UIViewKeyframeAnimationOptions(rawValue: UIViewAnimationOptions.CurveEaseOut.rawValue) } static var CurveLinear: UIViewKeyframeAnimationOptions { return UIViewKeyframeAnimationOptions(rawValue: UIViewAnimationOptions.CurveLinear.rawValue) } } 

现在你可以在UIView.animateKeyframesWithDuration方法中使用曲线选项

 let keyframeOptions: UIViewKeyframeAnimationOptions = [.Repeat, .CurveLinear] UIView.animateKeyframesWithDuration(duration, delay: delay, options: keyframeOptions, animations: { // add key frames here }, completion: nil)