2010-08-12 15 views
8

Estoy animando un péndulo que oscila de 0 grados a un máximo de 200 grados y luego de vuelta. El problema es que si el péndulo supera los 180 grados, vuelve a 0 por la ruta más corta que debe continuar en el sentido de las agujas del reloj. Y me gustaría que vaya en sentido antihorario. Aquí está mi código: ('derecho' es un valor lógico que es TRUE cuando el péndulo se balancea de izquierda a derecha)Forzar rotación en sentido horario/antihorario para un CABasicAnimación de un UIImageView

- (void)swingPendulum { 
    CABasicAnimation *rotationAnimation; 
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    if (right) 
     rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(kMax)]; 
    else 
     rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(kMin)];        
    rotationAnimation.duration = 1.0; 
    rotationAnimation.repeatCount = 1.0; 
    rotationAnimation.delegate = self; 
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 
    rotationAnimation.removedOnCompletion = NO; 

    [pendulum.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
} 

Alguna idea de cómo puedo hacer este trabajo? Es la pieza final de mi rompecabezas de mi cuentakilómetros que de otra manera funciona muy bien: D ¡Gracias!

Michael

Respuesta

8

Para conseguir que ir hacia la izquierda, acaba de establecer x a un valor negativo (añadir - delante) donde desea

rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(x)]; 
+0

Gracias por la respuesta, pero no parece marcar la diferencia, me temo. Establecerlo en un valor -ive solo parece hacer que la animación encaje al final ...Creo que tal vez debería volver a escribirlo para usar un NSTimer y animar la cosa fotograma a fotograma ... – Smikey

+0

En realidad, tienes razón, ya que kMin está actualmente configurado en -20, lo que hace que el péndulo oscile de hecho en sentido antihorario, pero solo si no pasa de 180 grados. Si va más allá de 180, entonces no importa en qué valor lo configure (-180, -90, 90, etc.), siempre continúa en sentido horario, incluso si no es la ruta más corta ... ¿Alguna otra idea? – Smikey

+1

AAAAH, si configuro un valor como -380, sin embargo, funciona. No estoy muy seguro de por qué, pero acabo de agregar una condición que cambia el valor aValue según si el swing inicial pasa 180 grados o no. ¡Gracias por toda la ayuda! – Smikey

0

No estoy seguro exactamente cuál es el problema, pero si se utiliza la función de auto reversa de la animación, es probable que pueda simplificar esto y hacer que gire (oscilación) de ida y vuelta. Esto funciona para mí:

CABasicAnimation* rotationAnimation = 
      [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
[rotationAnimation setToValue:[NSNumber numberWithFloat:DegreesToRadians(200.0)]]; 
[rotationAnimation setDuration:1.0]; 
[rotationAnimation setRepeatCount:HUGE_VALF]; // Repeat forever 
[rotationAnimation setAutoreverses:YES]; // Return to starting point 

[[pendulum layer] addAnimation:rotationAnimation forKey:nil]; 
+0

Una buena idea, pero el giro inverso no es una inversión exacta del giro hacia delante. Es decir. el swing hacia adelante comienza en 0, pero el swing hacia atrás cambia a -20. Así que prefiero llamar a una función que lo balancea desde su transformación actual a un ángulo específico. No estoy tratando de hacer un péndulo exactamente, sino más bien un oscilador de estilo de juego de golf: el jugador lo detiene una vez en el camino hacia arriba para poder y de nuevo en el camino hacia abajo para la precisión. Funciona perfectamente a menos que la barra supere los 180 grados en el camino hacia arriba, después de lo cual continuará en sentido antihorario hasta 0, en lugar de retroceder. Así que necesito forzar de alguna manera – Smikey

1

establecimiento de intentar algo así como

rotationAnimation.valueFunction = [CAValueFunction functionWithName:kCAValueFunctionRotateZ]; 

Utilización del valor de las funciones de transformación, las animaciones pueden afectar la propiedad transform de una capa de uso de transformaciones arbitrarias de cada componente (sin normalización a 360 °) y concatenar normalmente cuando se aplican múltiples animaciones a la vez.

Utiliza una función de transformación de valores que gira de 0 ° a 180 ° alrededor del eje z creando una función CAValueTransform que especifica el kCAValueFunctionRotateZ y luego crea una animación con fromValue de 0, a toValue of M_PI, y configura el valor de la animación propiedad de transformación a la instancia de transformación de valor.

+0

Gracias. Soy un poco reacio a cambiar el enfoque que ya estoy utilizando a menos que no haya forma de solucionarlo, ya que tengo muchos otros códigos que dependen de los métodos que ya he usado. Como comenté anteriormente, en realidad estoy creando un oscilador de estilo de juego de golf, en lugar de un péndulo, por lo que en cualquier momento el usuario puede interrumpir el columpio en el camino ascendente (para determinar la potencia) y se balanceará hacia atrás, para que el usuario pueda interrumpir nuevamente (para determinar la precisión). Tengo toda esta funcionalidad, aparte del hecho de que si el usuario deja que la barra oscile más de 180 grados, no retrocede, sino que avanza. – Smikey

+0

Intenta configurarlo y ver si funciona? Me da la impresión de que debería. –

+0

Lo hice - comenzó a comportarse bastante extraño ... ¡Tendré un poco más de violín y volveré! – Smikey

1

Yo creo que hay que usar este código:

[rotationAnimation.byValue = [NSNumber numberWithFloat:degreesToRadians(kMax/2))]; 
[rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(kMin)]; 
Cuestiones relacionadas