2011-07-21 28 views
6

Estoy creando una aplicación que implica animar líneas dentro de un área de trabajo a lo largo del tiempo. Mi enfoque actual para esto es usar un código como éste en drawRect:¿Cuál es la forma más fácil de animar una línea?

CGContextSetStrokeColor(context, black); 
CGContextBeginPath(context); 
CGContextMoveToPoint(context, startPoint.x, startPoint.y); 
CGContextAddLineToPoint(context, finalPoint.x, finalPoint.y); 
CGContextStrokePath(context); 

... y luego simplemente configurar un temporizador para que se ejecute cada 0,05 segundos para actualizar finalPoint y llame setNeedsDisplay.

Estoy encontrando este enfoque (cuando hay 5ish líneas que se mueven a la vez) ralentiza la aplicación terriblemente, e incluso con una frecuencia de actualización tan alta, todavía parece desigual.

Debe haber alguna forma mejor de realizar este dibujo de líneas muy simple en una línea animada, es decir diciendo que quiero que una línea comience en x1, y1 y se extienda a x2, y2 durante un período de tiempo determinado. ¿Cuáles son mis opciones para esto? Necesito hacer que esto funcione más rápido y me encantaría deshacerme de este temporizador torpe.

Gracias!

Respuesta

5

Utilice CAShapeLayers, y una combinación de CATransactions y CABasicAnimation.

Puede agregar una ruta de acceso determinada a shapeLayer y dejar que realice la representación.

Un objeto CAShapeLayer tiene dos propiedades llamadas strokeStart y strokeEnd, que definen a lo largo de la ruta que debe representar el final de la línea. Los valores predeterminados son 0.0 para strokeStart y 1.0 para strokeEnd.

Si configura su ruta para que strokeEnd inicialmente comience en 0.0, no verá línea.

A continuación, puede animar, de 0.0 a 1.0, la propiedad strokeEnd y verá que la línea se alarga.

Para cambiar implícita tiempo de animación por defecto de 0,25 s CAShapeLayer, puede agregar una función a la clase, así:

-(void)animateStrokeEnd:(CGFloat)_strokeEnd { 
    [CATransaction begin]; 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath]; 
    animation.duration = 2.0f; //or however long you want it to happen 
    animation.fromValue = [NSNumber numberWithFloat:self.strokeEnd]; // from the current strokeEnd value 
    animation.toValue = [NSNumber numberWithFloat:_strokeEnd]; //to the end of the path 
    [CATransaction setCompletionBlock:^{ self.strokeEnd = _strokeEnd }]; 
    [self addAnimation:animation forKey:@"animateStrokeEnd"]; 
    [CATransaction commit]; 
} 

Puede pasar cualquier valor de 0.0f a 1.0f como el valor de _strokeEnd.

El setCompletionBlock: asegura que el valor que está pasando se establece explícitamente después de que finaliza la animación.

Cuestiones relacionadas