AVISO: Cualquier pregunta que no cumpla ninguno de estos criterios podrá ser borrada sin previo aviso.

Bueno, creo que he escrito una pregunta un tanto liosa, os explico

Quiero realizar la animación de la aguja de un manómetro (la aguja de un cuentakilómetros es la misma idea). Tengo una imagen que representa a la circunferencia (donde estarían pintadas los números de la velocidad) y encima de esta tengo la imagen de una aguja.

La aguja al pintarse por primera vez lo hace en la posición inicial (lo que sería 0 Km/h) y cada x tiempo se debe refrescar con un valor que he obtenido y desplazarse a la posición adecuada.

Por ahora lo que he conseguido es que parta del inicio (0Km/h) se desplace un ángulo (p.ej. 180º) y se quede fijo en esa posición. Hasta aquí todo bien, la aguja al recibir un nuevo valor debería rotar desde la nueva posición que ha obtenido (180º) hasta la nueva (p.ej. 30º a la izquierda o 150º desde la posición inicial según se mire), pero el comportamiento que tiene realmente es que la imagen de la aguja se repinta otra vez en la posición inicial (la que se define en Interface Builder) e inicia la rotación desde 0º hasta la posición indicada.

¿Cómo puedo hacer que se desplace desde la última posición a la que rota?

Os dejo el método que estoy usando (basado en este ejemplo y en este otro) para realizar la animación:

#define M_PI   3.14159265358979323846264338327950288   /* pi */

// Nuestra conversión de grados a radianes
#define DEGREES_TO_RADIANS(angle) (angle / 180.0 * M_PI)

- (void)spinLayer:(CALayer *)inLayer duration:(CFTimeInterval)inDuration
            angle:(NSNumber *)angulo fromPreviousAngle:(NSNumber *)previousAngle{
    CABasicAnimation* rotationAnimation;

    // Rotate about the z axis
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

    // Rotamos según el angulo determinado, en caso de ser negativo irá en sentido contrario a las agujas del reloj y si es positivo rotará en el sentido 
    //de las agujas del reloj
    float anguloF = [angulo floatValue];
    rotationAnimation.toValue = [NSNumber numberWithFloat: DEGREES_TO_RADIANS(previousAngleF + anguloF)];

    // La duración de la animación
    rotationAnimation.duration = inDuration;

    //Se define la velocidad de animación
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    //Paramos la view en el final de la animación, pero al animarse de nuevo lo hace desde la posición inicial
    [rotationAnimation setFillMode:kCAFillModeForwards];
    [rotationAnimation setRemovedOnCompletion:NO];

    // Añade la animacion a la layer y la ejecuta
    [inLayer addAnimation:rotationAnimation forKey:@"rotationAnimation"];

}

A la llamada le paso como layer el layer de la ImageView de la aguja.

Muchas gracias a todos.

preguntado 03 Jun '11, 12:18

torhector2's gravatar image

torhector2
275283542

editó 03 Jun '11, 12:19


El error de que no se parase era un fallo descomunal mío, le estaba pasando como angulo previo siempre 0º de manera que empezaba siempre en el inicio ¬¬

Pero una vez arreglado este tema, la aguja ha empezado a dar vueltas como una loca (eso sí, partiendo siempre de la última posición), así que lo he arreglado cambiando la linea

rotationAnimation.toValue = [NSNumber numberWithFloat: DEGREES_TO_RADIANS(previousAngleF + anguloF)];

por esto

rotationAnimation.toValue = [NSNumber numberWithFloat: DEGREES_TO_RADIANS(anguloF)];

Aunque ahora el argumento "angulo" debería pasar a llamarse "incrementoAngulo" porque es eso lo que se le pasa, el ángulo que queremos que se desplace la aguja.

enlace permanente

respondido 03 Jun '11, 15:00

torhector2's gravatar image

torhector2
275283542

Intenta agregando

inLayer.transform = CATransform3DMakeRotation (DEGREES_TO_RADIANS(previousAngleF + anguloF), 0.0f, 0.0f, 1.0f);
enlace permanente

respondido 03 Jun '11, 13:50

Iv%C3%A1n%20Leider's gravatar image

Iván Leider ♦
1.4k626

¿Dónde debería ponerlo? Lo he puesto al final del método pero no ha cambiado de comportamiento, llega al final del recorrido, se queda en esa posición, pero cuando tiene que volver a girar empieza desde la primera posición de todas, desde cero.

(03 Jun '11, 14:06) torhector2

¿Existe algún protocolo que pueda implementar que se ejecute cuando la animación termine? Creo que sería ahí cuando debería aplicar lo que comenta Iván. Ahí o quizás antes de ejecutar la animación.

enlace permanente

respondido 03 Jun '11, 14:15

torhector2's gravatar image

torhector2
275283542

Tu respuesta:
Activar/desactivar vista previa