ios objective-c animation uiview core-animation

ios - UIView Infinite animación de rotación de 360 grados?



objective-c animation (26)

¡He desarrollado un marco de animación brillante que puede ahorrarle un poco de tiempo! Usándolo esta animación se puede crear muy fácilmente:

private var endlessRotater: EndlessAnimator! override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) let rotationAnimation = AdditiveRotateAnimator(M_PI).to(targetView).duration(2.0).baseAnimation(.CurveLinear) endlessRotater = EndlessAnimator(rotationAnimation) endlessRotater.animate() }

para detener esta animación simplemente establezca nil en endlessRotater .

Si está interesado, eche un vistazo: https://github.com/hip4yes/Animatics

Estoy tratando de rotar un UIImageView 360 grados, y he visto varios tutoriales en línea. No pude hacer que ninguno de ellos trabajara, sin que el UIView detuviera o saltara a una nueva posición.

  • ¿Cómo puedo conseguir esto?

Lo último que he probado es:

[UIView animateWithDuration:1.0 delay:0.0 options:0 animations:^{ imageToMove.transform = CGAffineTransformMakeRotation(M_PI); } completion:^(BOOL finished){ NSLog(@"Done!"); }];

Pero si uso 2 * pi, no se mueve en absoluto (ya que es la misma posición). Si trato de hacer solo pi (180 grados), funciona, pero si vuelvo a llamar al método, gira hacia atrás.

EDITAR :

[UIView animateWithDuration:1.0 delay:0.0 options:0 animations:^{ [UIView setAnimationRepeatCount:HUGE_VALF]; [UIView setAnimationBeginsFromCurrentState:YES]; imageToMove.transform = CGAffineTransformMakeRotation(M_PI); } completion:^(BOOL finished){ NSLog(@"Done!"); }];

Tampoco funciona. Va a 180 grados, se detiene por una fracción de segundo, luego se restablece a 0 grados antes de que comience nuevamente.


Aquí está mi solución rápida como una extensión UIView. Podría considerarse como una simulación de un comportamiento UIActivityIndicator en cualquier UIImageView.

import UIKit extension UIView { /** Starts rotating the view around Z axis. @param duration Duration of one full 360 degrees rotation. One second is default. @param repeatCount How many times the spin should be done. If not provided, the view will spin forever. @param clockwise Direction of the rotation. Default is clockwise (true). */ func startZRotation(duration duration: CFTimeInterval = 1, repeatCount: Float = Float.infinity, clockwise: Bool = true) { if self.layer.animationForKey("transform.rotation.z") != nil { return } let animation = CABasicAnimation(keyPath: "transform.rotation.z") let direction = clockwise ? 1.0 : -1.0 animation.toValue = NSNumber(double: M_PI * 2 * direction) animation.duration = duration animation.cumulative = true animation.repeatCount = repeatCount self.layer.addAnimation(animation, forKey:"transform.rotation.z") } /// Stop rotating the view around Z axis. func stopZRotation() { self.layer.removeAnimationForKey("transform.rotation.z") } }


Así es como giro 360 en la dirección correcta.

[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionRepeat|UIViewAnimationOptionCurveLinear animations:^{ [imageIndView setTransform:CGAffineTransformRotate([imageIndView transform], M_PI-0.00001f)]; } completion:nil];


Crear la animacion

- (CABasicAnimation *)spinAnimationWithDuration:(CGFloat)duration clockwise:(BOOL)clockwise repeat:(BOOL)repeats { CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; anim.toValue = clockwise ? @(M_PI * 2.0) : @(M_PI * -2.0); anim.duration = duration; anim.cumulative = YES; anim.repeatCount = repeats ? CGFLOAT_MAX : 0; return anim; }

Añádelo a una vista como esta.

CABasicAnimation *animation = [self spinAnimationWithDuration:1.0 clockwise:YES repeat:YES]; [self.spinningView.layer addAnimation:animation forKey:@"rotationAnimation"];

¿En qué se diferencia esta respuesta? Tendrá un código más limpio si la mayoría de sus funciones devuelve objetos en lugar de solo manipular algunos objetos aquí y allá.


Creo que deberías agregar una categoría UIVIew :

#import <QuartzCore/QuartzCore.h> #import "UIView+Rotate.h"

Implementación UIView (Rotar)

  • (void)remrotate360WithDuration:(CGFloat)duration repeatCount: (float)repeatCount { CABasicAnimation *fullRotation; fullRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; fullRotation.fromValue = [NSNumber numberWithFloat:0]; fullRotation.toValue = [NSNumber numberWithFloat:(2*M_PI)]; // fullRotation.toValue = [NSNumber numberWithFloat:-(2*M_PI)]; // added this minus sign as i want to rotate it to anticlockwise fullRotation.duration = duration; fullRotation.speed = 2.0f; // Changed rotation speed if (repeatCount == 0) fullRotation.repeatCount = MAXFLOAT; else fullRotation.repeatCount = repeatCount; [self.layer addAnimation:fullRotation forKey:@"360"]; }

No utilizando estos métodos :)

  • (void)remstopAllAnimations { [self.layer removeAllAnimations]; };

  • (void)rempauseAnimations { [self rempauseLayer:self.layer]; }

  • (void)remresumeAnimations { [self remresumeLayer:self.layer]; }

  • (void)rempauseLayer:(CALayer *)layer { CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; layer.speed = 0.0; layer.timeOffset = pausedTime; }

  • (void)remresumeLayer:(CALayer *)layer { CFTimeInterval pausedTime = [layer timeOffset]; layer.speed = 1.0; layer.timeOffset = 0.0; layer.beginTime = 0.0; CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; layer.beginTime = timeSincePause; }


En Swift, puedes usar el siguiente código para la rotación infinita:

Swift 4

extension UIView { private static let kRotationAnimationKey = "rotationanimationkey" func rotate(duration: Double = 1) { if layer.animation(forKey: UIView.kRotationAnimationKey) == nil { let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation") rotationAnimation.fromValue = 0.0 rotationAnimation.toValue = Float.pi * 2.0 rotationAnimation.duration = duration rotationAnimation.repeatCount = Float.infinity layer.add(rotationAnimation, forKey: UIView.kRotationAnimationKey) } } func stopRotating() { if layer.animation(forKey: UIView.kRotationAnimationKey) != nil { layer.removeAnimation(forKey: UIView.kRotationAnimationKey) } } }

Swift 3

let kRotationAnimationKey = "com.myapplication.rotationanimationkey" // Any key func rotateView(view: UIView, duration: Double = 1) { if view.layer.animationForKey(kRotationAnimationKey) == nil { let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation") rotationAnimation.fromValue = 0.0 rotationAnimation.toValue = Float(M_PI * 2.0) rotationAnimation.duration = duration rotationAnimation.repeatCount = Float.infinity view.layer.addAnimation(rotationAnimation, forKey: kRotationAnimationKey) } }

Parar es como

func stopRotatingView(view: UIView) { if view.layer.animationForKey(kRotationAnimationKey) != nil { view.layer.removeAnimationForKey(kRotationAnimationKey) } }


Encontré un método (lo modifiqué un poco) que funcionó perfectamente para mí: rotación de UIImageView del iPhone

#import <QuartzCore/QuartzCore.h> - (void) runSpinAnimationOnView:(UIView*)view duration:(CGFloat)duration rotations:(CGFloat)rotations repeat:(float)repeat { CABasicAnimation* rotationAnimation; rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * rotations * duration ]; rotationAnimation.duration = duration; rotationAnimation.cumulative = YES; rotationAnimation.repeatCount = repeat ? HUGE_VALF : 0; [view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; }


Esto estaba trabajando para mí:

[UIView animateWithDuration:1.0 animations:^ { self.imageView.transform = CGAffineTransformMakeRotation(M_PI); self.imageView.transform = CGAffineTransformMakeRotation(0); }];


Felicitaciones a Richard J. Ross III por la idea, pero descubrí que su código no era exactamente lo que necesitaba. El valor predeterminado para las options , creo, es darle UIViewAnimationOptionCurveEaseInOut , que no se ve bien en una animación continua. Además, agregué un cheque para poder detener mi animación en un cuarto de giro si lo necesitaba (no infinito , pero de duración indefinida ), e hice que la aceleración aumentara durante los primeros 90 grados, y desacelerara durante los últimos 90 grados (después de una parada ha sido solicitada):

// an ivar for your class: BOOL animating; - (void)spinWithOptions:(UIViewAnimationOptions)options { // this spin completes 360 degrees every 2 seconds [UIView animateWithDuration:0.5 delay:0 options:options animations:^{ self.imageToMove.transform = CGAffineTransformRotate(imageToMove.transform, M_PI / 2); } completion:^(BOOL finished) { if (finished) { if (animating) { // if flag still set, keep spinning with constant speed [self spinWithOptions: UIViewAnimationOptionCurveLinear]; } else if (options != UIViewAnimationOptionCurveEaseOut) { // one last spin, with deceleration [self spinWithOptions: UIViewAnimationOptionCurveEaseOut]; } } }]; } - (void)startSpin { if (!animating) { animating = YES; [self spinWithOptions: UIViewAnimationOptionCurveEaseIn]; } } - (void)stopSpin { // set the flag to stop spinning after one last 90 degree increment animating = NO; }

Actualizar

startSpin la capacidad de manejar solicitudes para comenzar a girar nuevamente ( startSpin ), mientras que el giro anterior se está reduciendo (completando). Proyecto de muestra aquí en Github .


Hay diferentes formas de realizar una animación de 360 ​​grados con UIView.

Usando CABasicAnimation

var rotationAnimation = CABasicAnimation() rotationAnimation = CABasicAnimation.init(keyPath: "transform.rotation.z") rotationAnimation.toValue = NSNumber(value: (Double.pi)) rotationAnimation.duration = 1.0 rotationAnimation.isCumulative = true rotationAnimation.repeatCount = 100.0 view.layer.add(rotationAnimation, forKey: "rotationAnimation")


Aquí hay una extensión de funciones para UIView que maneja las operaciones de rotación de inicio y parada:

extension UIView { // Start rotation func startRotation() { let rotation = CABasicAnimation(keyPath: "transform.rotation.z") rotation.fromValue = 0 rotation.toValue = NSNumber(value: Double.pi) rotation.duration = 1.0 rotation.isCumulative = true rotation.repeatCount = FLT_MAX self.layer.add(rotation, forKey: "rotationAnimation") } // Stop rotation func stopRotation() { self.layer.removeAnimation(forKey: "rotationAnimation") } }


Ahora usando, cierre de UIView.animation :

UIView.animate(withDuration: 0.5, animations: { view.transform = CGAffineTransform(rotationAngle: (CGFloat(Double.pi)) }) { (isAnimationComplete) in // Animation completed }


He encontrado código agradable en este repository ,

Aquí está el código del que he hecho pequeños cambios de acuerdo con mi necesidad de velocidad :)

UIImageView + Rotate.h

#import <Foundation/Foundation.h> @interface UIImageView (Rotate) - (void)rotate360WithDuration:(CGFloat)duration repeatCount:(float)repeatCount; - (void)pauseAnimations; - (void)resumeAnimations; - (void)stopAllAnimations; @end

UIImageView + Rotate.m

#import <QuartzCore/QuartzCore.h> #import "UIImageView+Rotate.h" @implementation UIImageView (Rotate) - (void)rotate360WithDuration:(CGFloat)duration repeatCount:(float)repeatCount { CABasicAnimation *fullRotation; fullRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; fullRotation.fromValue = [NSNumber numberWithFloat:0]; //fullRotation.toValue = [NSNumber numberWithFloat:(2*M_PI)]; fullRotation.toValue = [NSNumber numberWithFloat:-(2*M_PI)]; // added this minus sign as i want to rotate it to anticlockwise fullRotation.duration = duration; fullRotation.speed = 2.0f; // Changed rotation speed if (repeatCount == 0) fullRotation.repeatCount = MAXFLOAT; else fullRotation.repeatCount = repeatCount; [self.layer addAnimation:fullRotation forKey:@"360"]; } //Not using this methods :) - (void)stopAllAnimations { [self.layer removeAllAnimations]; }; - (void)pauseAnimations { [self pauseLayer:self.layer]; } - (void)resumeAnimations { [self resumeLayer:self.layer]; } - (void)pauseLayer:(CALayer *)layer { CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; layer.speed = 0.0; layer.timeOffset = pausedTime; } - (void)resumeLayer:(CALayer *)layer { CFTimeInterval pausedTime = [layer timeOffset]; layer.speed = 1.0; layer.timeOffset = 0.0; layer.beginTime = 0.0; CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; layer.beginTime = timeSincePause; } @end


La answer @ ram fue realmente útil. Aquí está una versión rápida de la respuesta.

private func rotateImageView() { UIView.animateWithDuration(1, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: { () -> Void in self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, CGFloat(M_PI_2)) }) { (finished) -> Void in if finished { self.rotateImageView() } } }


La asombrosa respuesta de David Rysanek actualizada a Swift 4 :

import UIKit extension UIView { func startRotating(duration: CFTimeInterval = 3, repeatCount: Float = Float.infinity, clockwise: Bool = true) { if self.layer.animation(forKey: "transform.rotation.z") != nil { return } let animation = CABasicAnimation(keyPath: "transform.rotation.z") let direction = clockwise ? 1.0 : -1.0 animation.toValue = NSNumber(value: .pi * 2 * direction) animation.duration = duration animation.isCumulative = true animation.repeatCount = repeatCount self.layer.add(animation, forKey:"transform.rotation.z") } func stopRotating() { self.layer.removeAnimation(forKey: "transform.rotation.z") } } }


La respuesta anterior de Nate es ideal para detener y comenzar la animación y brinda un mejor control. Estaba intrigado por qué el tuyo no funcionó y el suyo sí. Quería compartir mis hallazgos aquí y una versión más simple del código que animaría un UIView continuamente sin detenerse.

Este es el código que usé,

- (void)rotateImageView { [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ [self.imageView setTransform:CGAffineTransformRotate(self.imageView.transform, M_PI_2)]; }completion:^(BOOL finished){ if (finished) { [self rotateImageView]; } }]; }

Utilicé ''CGAffineTransformRotate'' en lugar de ''CGAffineTransformMakeRotation'' porque el primero devuelve el resultado que se guarda a medida que avanza la animación. Esto evitará el salto o restablecimiento de la vista durante la animación.

Otra cosa es no usar ''UIViewAnimationOptionRepeat'' porque al final de la animación, antes de que comience a repetirse, restablece la transformación haciendo que la vista vuelva a su posición original. En lugar de una repetición, recuenta para que la transformación nunca se restablezca al valor original porque el bloque de animación prácticamente nunca termina.

Y lo último es que debe transformar la vista en pasos de 90 grados (M_PI / 2) en lugar de 360 ​​o 180 grados (2 * M_PI o M_PI). Porque la transformación se produce como una matriz de multiplicación de los valores de seno y coseno.

t'' = [ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ] * t

Entonces, digamos que si usa la transformación de 180 grados, el coseno de 180 produce -1 transformando la vista en dirección opuesta cada vez (la respuesta de Note-Nate también tendrá este problema si cambia el valor de transformación de radianes a M_PI). Una transformación de 360 ​​grados es simplemente pedirle a la vista que permanezca donde estaba, por lo tanto, no ve ninguna rotación en absoluto.


Mi contribución con una extensión Swift de la solución comprobada:

Swift 4.0

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

Obsoleto :

extension UIView{ func rotate() { let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") rotation.toValue = NSNumber(double: M_PI * 2) rotation.duration = 1 rotation.cumulative = true rotation.repeatCount = FLT_MAX self.layer.addAnimation(rotation, forKey: "rotationAnimation") } }


Si alguien quería la solución de Nates pero en forma rápida, aquí hay una traducción rápida:

class SomeClass: UIViewController { var animating : Bool = false @IBOutlet weak var activityIndicatorImage: UIImageView! func startSpinning() { if(!animating) { animating = true; spinWithOptions(UIViewAnimationOptions.CurveEaseIn); } } func stopSpinning() { animating = false } func spinWithOptions(options: UIViewAnimationOptions) { UIView.animateWithDuration(0.5, delay: 0.0, options: options, animations: { () -> Void in let val : CGFloat = CGFloat((M_PI / Double(2.0))); self.activityIndicatorImage.transform = CGAffineTransformRotate(self.activityIndicatorImage.transform,val) }) { (finished: Bool) -> Void in if(finished) { if(self.animating){ self.spinWithOptions(UIViewAnimationOptions.CurveLinear) } else if (options != UIViewAnimationOptions.CurveEaseOut) { self.spinWithOptions(UIViewAnimationOptions.CurveEaseOut) } } } } override func viewDidLoad() { startSpinning() } }


Si todo lo que quieres hacer es rotar la imagen sin fin, esto funciona bastante bien y es muy simple:

NSTimeInterval duration = 10.0f; CGFloat angle = M_PI / 2.0f; CGAffineTransform rotateTransform = CGAffineTransformRotate(imageView.transform, angle); [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{ imageView.transform = rotateTransform; } completion:nil];

En mi experiencia, esto funciona a la perfección, pero asegúrese de que su imagen pueda girarse alrededor de su centro sin ningún tipo de desplazamiento, o la animación de la imagen "saltará" una vez que llegue a PI.

Para cambiar la dirección del giro, cambie el signo de angle ( angle *= -1 ).

Los comentarios de actualización de @AlexPretzlav me hicieron volver a esto, y me di cuenta de que cuando escribí esto, la imagen que estaba girando se reflejaba tanto en el eje vertical como en el horizontal, lo que significa que la imagen solo giraba 90 grados y luego se restablecía, aunque parecía Continuaba girando todo el tiempo alrededor.

Entonces, si su imagen es como la mía, esto funcionará bien, sin embargo, si la imagen no es simétrica, notará que el "ajuste" vuelve a la orientación original después de 90 grados.

Para rotar una imagen no simétrica, mejor con la respuesta aceptada.

Una de estas soluciones menos elegantes, que se ve a continuación, realmente rotará la imagen, pero puede haber un tartamudeo notable cuando se reinicia la animación:

- (void)spin { NSTimeInterval duration = 0.5f; CGFloat angle = M_PI_2; CGAffineTransform rotateTransform = CGAffineTransformRotate(self.imageView.transform, angle); [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ self.imageView.transform = rotateTransform; } completion:^(BOOL finished) { [self spin]; }]; }

También puede hacer esto solo con bloques, como sugiere @ richard-j-ross-iii, pero recibirá una advertencia de bucle de retención ya que el bloque se está capturando a sí mismo:

__block void(^spin)() = ^{ NSTimeInterval duration = 0.5f; CGFloat angle = M_PI_2; CGAffineTransform rotateTransform = CGAffineTransformRotate(self.imageView.transform, angle); [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ self.imageView.transform = rotateTransform; } completion:^(BOOL finished) { spin(); }]; }; spin();


Swift 3:

var rotationAnimation = CABasicAnimation() rotationAnimation = CABasicAnimation.init(keyPath: "transform.rotation.z") rotationAnimation.toValue = NSNumber(value: (M_PI * 2.0)) rotationAnimation.duration = 2.0 rotationAnimation.isCumulative = true rotationAnimation.repeatCount = 10.0 view.layer.add(rotationAnimation, forKey: "rotationAnimation")


También puedes hacer el mismo tipo de animación usando UIView y bloques. Aquí hay un método de extensión de clase que puede rotar la vista en cualquier ángulo.

- (void)rotationWithDuration:(NSTimeInterval)duration angle:(CGFloat)angle options:(UIViewAnimationOptions)options { // Repeat a quarter rotation as many times as needed to complete the full rotation CGFloat sign = angle > 0 ? 1 : -1; __block NSUInteger numberRepeats = floorf(fabsf(angle) / M_PI_2); CGFloat quarterDuration = duration * M_PI_2 / fabs(angle); CGFloat lastRotation = angle - sign * numberRepeats * M_PI_2; CGFloat lastDuration = duration - quarterDuration * numberRepeats; __block UIViewAnimationOptions startOptions = UIViewAnimationOptionBeginFromCurrentState; UIViewAnimationOptions endOptions = UIViewAnimationOptionBeginFromCurrentState; if (options & UIViewAnimationOptionCurveEaseIn || options == UIViewAnimationOptionCurveEaseInOut) { startOptions |= UIViewAnimationOptionCurveEaseIn; } else { startOptions |= UIViewAnimationOptionCurveLinear; } if (options & UIViewAnimationOptionCurveEaseOut || options == UIViewAnimationOptionCurveEaseInOut) { endOptions |= UIViewAnimationOptionCurveEaseOut; } else { endOptions |= UIViewAnimationOptionCurveLinear; } void (^lastRotationBlock)(void) = ^ { [UIView animateWithDuration:lastDuration delay:0 options:endOptions animations:^{ self.transform = CGAffineTransformRotate(self.transform, lastRotation); } completion:^(BOOL finished) { NSLog(@"Animation completed"); } ]; }; if (numberRepeats) { __block void (^quarterSpinningBlock)(void) = ^{ [UIView animateWithDuration:quarterDuration delay:0 options:startOptions animations:^{ self.transform = CGAffineTransformRotate(self.transform, M_PI_2); numberRepeats--; } completion:^(BOOL finished) { if (numberRepeats > 0) { startOptions = UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveLinear; quarterSpinningBlock(); } else { lastRotationBlock(); }NSLog(@"Animation completed"); } ]; }; quarterSpinningBlock(); } else { lastRotationBlock(); } }


Una versión de Swift3:

extension UIView { func startRotate() { let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") rotation.fromValue = 0 rotation.toValue = NSNumber(value: M_PI * 2) rotation.duration = 2 rotation.isCumulative = true rotation.repeatCount = FLT_MAX self.layer.add(rotation, forKey: "rotationAnimation") } func stopRotate() { self.layer.removeAnimation(forKey: "rotationAnimation") } }

Y recuerde llamar a startRotate en viewWillAppear no en viewDidLoad .


Use cuarto de vuelta y aumente el turno incrementalmente.

void (^block)() = ^{ imageToMove.transform = CGAffineTransformRotate(imageToMove.transform, M_PI / 2); } void (^completion)(BOOL) = ^(BOOL finished){ [UIView animateWithDuration:1.0 delay:0.0 options:0 animations:block completion:completion]; } completion(YES);


para xamarin ios:

public static void RotateAnimation (this UIView view, float duration=1, float rotations=1, float repeat=int.MaxValue) { var rotationAnimation = CABasicAnimation.FromKeyPath ("transform.rotation.z"); rotationAnimation.To = new NSNumber (Math.PI * 2.0 /* full rotation*/ * 1 * 1); rotationAnimation.Duration = 1; rotationAnimation.Cumulative = true; rotationAnimation.RepeatCount = int.MaxValue; rotationAnimation.RemovedOnCompletion = false; view.Layer.AddAnimation (rotationAnimation, "rotationAnimation"); }


Swift 4.0

func rotateImageView() { UIView.animate(withDuration: 0.3, delay: 0, options: .curveLinear, animations: {() -> Void in self.imageView.transform = self.imageView.transform.rotated(by: .pi / 2) }, completion: {(_ finished: Bool) -> Void in if finished { rotateImageView() } }) }


Swift 4 ,

func rotateImage(image: UIImageView) { UIView.animate(withDuration: 1, animations: { image.transform = CGAffineTransform(rotationAngle: CGFloat.pi) image.transform = CGAffineTransform.identity }) { (completed) in self.rotateImage() } }

Ref


Swift:

func runSpinAnimationOnView(view:UIView , duration:Float, rotations:Double, repeatt:Float ) ->() { let rotationAnimation=CABasicAnimation(); rotationAnimation.keyPath="transform.rotation.z" let toValue = M_PI * 2.0 * rotations ; // passing it a float let someInterval = CFTimeInterval(duration) rotationAnimation.toValue=toValue; rotationAnimation.duration=someInterval; rotationAnimation.cumulative=true; rotationAnimation.repeatCount=repeatt; view.layer.addAnimation(rotationAnimation, forKey: "rotationAnimation") }


let val = CGFloat(M_PI_2) UIView.animate(withDuration: 1, delay: 0, options: [.repeat, .curveLinear], animations: { self.viewToRotate.transform = self.viewToRotate.transform.rotated(by: val) })