使用animateKeyframesWithDuration在屏幕上创建一个连续旋转的方块

时间:2014-10-30 23:22:47

标签: ios animation swift rotation repeat

我尝试使用下面的代码在屏幕上创建一个连续旋转的方块。但我不知道为什么转速会发生变化。如何更改代码以使旋转速度不变?我尝试了不同的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
        })
    }         

4 个答案:

答案 0 :(得分:8)

之前我遇到过同样的问题,这就是我的工作方式:

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

我在放弃之前就把这个问题弄清楚了。我不认为有关于它的文档,但它只是起作用。

答案 1 :(得分:4)

这真的很奇怪... UIView.animateKeyframesWithDuration无法正常工作,因为UIViewKeyframeAnimationOptions.CalculationModeLinear|UIViewKeyframeAnimationOpti‌​ons.Repeat传入了选项。

如果使用非块方法创建关键帧动画(见下文),则旋转会按预期重复。<​​/ p>

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

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

}

答案 2 :(得分:1)

添加UIViewKeyframeAnimationOptionCalculationModeLinear执行您的关键帧选项。 UIView动画的默认行为是&#34;轻松进/出&#34;动画片即,开始缓慢,加速,然后在接近结束时再次减速。

答案 3 :(得分:0)

AFAIU,这是因为默认动画曲线为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)