2012-06-19 14 views
5

Estoy usando una animación de rotación creada con CABasicAnimation. Gira un UIView durante 2 segundos. Pero necesito poder detenerlo cuando se toca el UIView. Si elimino la animación, la vista está en la misma posición que antes de que comenzara la animación.Detener CABasicAnimation en el punto específico

Aquí está mi código de animación:

float duration = 2.0; 
float rotationAngle = rotationDirection * ang * speed * duration; 
//rotationAngle = 3*(2*M_PI);//(double)rotationAngle % (double)(2*M_PI) ; 
CABasicAnimation* rotationAnimation; 
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
rotationAnimation.toValue = [NSNumber numberWithFloat: rotationAngle ]; 
rotationAnimation.duration = duration; 
rotationAnimation.cumulative = YES; 
rotationAnimation.removedOnCompletion = NO; 
rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 
rotationAnimation.fillMode = kCAFillModeForwards; 
rotationAnimation.delegate = self; 

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

¿Cómo puedo dejar de derecho de giro del UIView 's donde está, cuando se ha tocado? Sé cómo administrar la parte táctil, pero no puedo imaginar cómo detener la vista en el ángulo actual de la animación.

Solución: Resolví el problema obteniendo el ángulo de la capa de presentación, eliminando la animación y configurando la transformación de la vista. Aquí está el código:

[self.view.layer removeAllAnimations];  
CALayer* presentLayer = self.view.layer.presentationLayer; 
float currentAngle = [(NSNumber *)[presentLayer valueForKeyPath:@"transform.rotation.z"] floatValue]; 
self.view.transform = CGAffineTransformMakeRotation(currentAngle); 
+1

dónde se pone la solución anterior ?? Siempre obtengo el ángulo 0.0000 – Hisenberg

Respuesta

15

Buena pregunta! Para esto, es útil conocer la arquitectura Core Animation.

Si mira el diagrama en el Core Animation Programming Guide que describe la arquitectura de renderizado de animación principal, puede ver que hay tres árboles.

Tiene el modelo árbol. Ahí es donde establece los valores de lo que quiere que suceda. Luego está el árbol de presentación. Eso es lo que sucede en lo que respecta al tiempo de ejecución. Entonces, finalmente es el render árbol. Eso es lo que el usuario ve.

En su caso, desea consultar los valores del árbol de presentación.

Es fácil de hacer. Para ver que ha adjuntado la animación, obtenga el layer y para eso layer, consulte los valores de presentationLayer. Por ejemplo:

CATransform3D myTransform = [(CALayer*)[self.view.layer presentationLayer] transform]; 

No hay forma de "pausar" un flujo intermedio de animación. Todo lo que puede hacer es consultar los valores, eliminarlos y volver a crearlos desde donde los dejó.

¡Es un poco doloroso!

Eche un vistazo a algunas de mis otras publicaciones donde profundizo en esto con más detalle, p. Ej.

Restoring animation where it left off when app resumes from background

No se olvide también que, al añadir una animación a la capa de una vista, no está realmente cambiando las propiedades de la vista subyacente. ¿Así que lo que ocurre?Obtendremos efectos extraños cuando la animación se detenga y vea la vista en su posición original.

Ahí es donde necesita utilizar los delegados CAAnimation. Echar un vistazo a mi respuesta a esta entrada, donde cubro esto:

CABasicAnimation rotate returns to original position

+1

Gracias por la explicación de la capa de presentación. Resolví el problema obteniendo el ángulo de rotación de presentationLayer con valueForKeyPath :, estableciendo la transformación de la vista y eliminando la animación. –

5

Es necesario configurar la rotación de la rotación de la presentationLayer y luego retire la animación de la capa. Puede leer sobre la capa de presentación en mi blog sobre Hit testing animating layers.

El código para establecer la rotación final sería algo así como:

self.view.layer.transform = [(CALayer*)[self.view.layer presentationLayer] transform]; 
[self.view.layer removeAnimationForKey:@"rotationAnimation"]; 
Cuestiones relacionadas