Crea un cuadrado que gira continuamente en la pantalla usando animateKeyframesWithDuration

Traté de usar el código de abajo para crear un cuadro giratorio en forma continua en la pantalla. Pero no sé por qué la velocidad de rotation está cambiando. ¿Cómo podría cambiar el código para que la velocidad de rotation sea invariable? UIViewKeyframeAnimationOptions diferentes UIViewKeyframeAnimationOptions , pero parece que ninguno de ellos funciona.

 override func viewDidLoad() { super.viewDidLoad() let square = UIView() square.frame = CGRect(x: 55, y: 300, width: 40, height: 40) square.backgroundColor = UIColor.networkingColor() 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 }) } 

Eso es realmente extraño … UIView.animateKeyframesWithDuration no funciona como lo esperaría con UIViewKeyframeAnimationOptions.CalculationModeLinear|UIViewKeyframeAnimationOpti‌​ons.Repeat pasó con opciones.

Si usa el método no bloqueado para crear una animation de fotogtwigs key (ver a continuación), la rotation se repite como se esperaba.

Si descubro por qué la opción basada en bloques no funciona, intentaré y también recordaré actualizar la respuesta aquí.

 override func viewDidLoad() { super.viewDidLoad() let square = UIView() square.frame = CGRect(x: 55, y: 300, width: 40, height: 40) square.backgroundColor = UIColor.networkingColor() 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") } 

Me enfrenté al mismo problema antes, así es como lo hago funcionar:

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

Me imaginé que este problema justo antes lo abandonó. No creo que haya doc al respecto, pero simplemente funciona.

Agregue UIViewKeyframeAnimationOptionCalculationModeLinear haga sus opciones de fotogtwigs key. El comportamiento pnetworkingeterminado para las animaciones de UIView es "facilitar la input / salida" de la animation. es decir, comience despacio, vaya a la velocidad, luego networkinguzca la velocidad nuevamente justo al final.

AFAIU, esto está sucediendo porque la curva de animation pnetworkingeterminada es UIViewAnimationOption.CurveEaseInOut .

Desafortunadamente, UIViewKeyframeAnimationOptions no tiene opciones para cambiar la curva, ¡pero puede agregarlas manualmente!

Use esta extensión:

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

Ahora puede usar las opciones de curva en el método UIView.animateKeyframesWithDuration

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