2012-10-10 25 views
5

Estoy animando un brazo de reloj que apunta hacia las 12 en punto a la hora actual. Si es así, a las 11 en punto, quiero que el brazo gire en el sentido de las agujas del reloj hasta la posición de las 11 en punto. Pero por supuesto si uso:Gire un UIView en el sentido de las agujas del reloj para un ángulo superior a 180 grados

CGAffineTransform rotation = CGAffineTransformMakeRotation(2*M_PI*11/12); 

[UIView animateWithDuration:3.0 
        animations:^{ 
         clockArm.transform = rotation; 
        }]; 

la rotación va en sentido antihorario. Probé:

CGFloat angle = 2*M_PI*11/12; 
CGAffineTransform firstRotation = CGAffineTransformMakeRotation(M_PI-0.001); 
CGFloat firstRotationTime = 3.0*(M_PI/angle); 
CGAffineTransform secondRotation = CGAffineTransformMakeRotation(angle); 
CGFloat secondRotationTime = 3.0 - firstRotationTime; 

[UIView animateWithDuration:firstRotationTime 
         delay:0.0 
        options:UIViewAnimationCurveLinear 
       animations:^{ 
         self.clockArm1.transform = firstRotation; 
        } 
       completion:^(BOOL finished) { 
        [UIView animateWithDuration:secondRotationTime 
              delay:0.0 
             options:UIViewAnimationCurveLinear 
             animations:^{ 
              self.clockArm1.transform = secondRotation; 
             } 
             completion:^(BOOL finished){ 
             }]; 
       }]; 

La animación no ir hacia la derecha, pero no es claro - la animación todavía parece estar haciendo un UIViewAnimationEaseInOut por primera animación. ¿Qué estoy haciendo mal, o hay otra forma de lograr lo que quiero?

+0

Tenga una mirada en la respuesta aceptada de http://stackoverflow.com/questions/9844925/uiview-infinite -360-degree-rotation-animation. ¿Eso ayuda? –

Respuesta

5

Usted puede utilizar el bloque de terminación de CATransaction para establecer la propiedad de rotación de la vista cuando la animación ha terminado. La siguiente función trabajado en mi caso de prueba:

- (void) rotateViewAnimated:(UIView*)view 
       withDuration:(CFTimeInterval)duration 
        byAngle:(CGFloat)angle 
{ 
    [CATransaction begin]; 
    CABasicAnimation *rotationAnimation; 
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    rotationAnimation.byValue = [NSNumber numberWithFloat:angle]; 
    rotationAnimation.duration = duration; 
    rotationAnimation.removedOnCompletion = YES; 

    [CATransaction setCompletionBlock:^{ 
     view.transform = CGAffineTransformRotate(view.transform, angle); 
    }]; 

    [view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
    [CATransaction commit]; 
} 

que lo utilice como

[self rotateViewAnimated:self.clockArm1 withDuration:3.0 byAngle:2*M_PI*11./12.]; 
+0

Eso parece funcionar, ¡gracias! – Darren

1

Como se mencionó en los comentarios, prueba este iphone UIImageView rotation o UIView Infinite 360 degree rotation animation?

#import <QuartzCore/QuartzCore.h> 

- (void) runSpinAnimationWithDuration:(CGFloat) duration; 
{ 
    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 = 1.0; 
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 

    [myView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
} 
+0

Gracias, eso funcionó para la animación, pero por alguna razón después de que la animación se complete mi manecilla de reloj regresa a la posición de las 12 en punto. Intenté consultar la documentación sobre CABasicAnimation, CAPropertyAnimation y CAAnimation. Intenté configurar la propiedad removedOnCompletion en NO, pero no he podido averiguar cómo lograr que la transformación persista. – Darren

3

Gracias por respuesta aceptada @ Martin R 's. I editado un poco:

Substituí esta línea

rotationAnimation.removedOnCompletion = YES; 

con estas dos líneas:

rotationAnimation.removedOnCompletion = NO; 
rotationAnimation.fillMode = kCAFillModeForwards; 

Luego, en la CompletionBlock, añadí una línea más:

[view.layer removeAllAnimations]; 

Entonces, el código finalmente se convierte en:

- (void) rotateViewAnimated:(UIView*)view 
      withDuration:(CFTimeInterval)duration 
       byAngle:(CGFloat)angle 
    { 
     [CATransaction begin]; 
     CABasicAnimation *rotationAnimation; 
     rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
     rotationAnimation.byValue = [NSNumber numberWithFloat:angle]; 
     rotationAnimation.duration = duration; 
     // changed by me 
     rotationAnimation.removedOnCompletion = NO; 
     rotationAnimation.fillMode = kCAFillModeForwards; 


     [CATransaction setCompletionBlock:^{ 
     view.transform = CGAffineTransformRotate(view.transform, angle); 
     // added by me 
     [view.layer removeAllAnimations]; // this is important 

     }]; 

    [view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
    [CATransaction commit]; 

    } 

Mis referencias son de:

1, https://stackoverflow.com/a/3586433/2481444

2, After rotating a CALayer using CABasicAnimation the layer jumps back to it's unrotated position

Cuestiones relacionadas