7

Intento animar la apariencia de un segmento de un círculo. Para archivar esto, uso CABasicAnimations, que funciona muy bien.La animación del trazo del segmento circular termina en trazo completo

La animación comienza en la parte superior y se mueve muy bien tranquila a un tercio de todo el círculo. Pero cuando termina la animación, el círculo se dibuja completamente de inmediato.

¿Cómo puedo evitar eso?

Aquí está el código fuente de mi UIView personalizado:

- (void)drawRect:(CGRect)rect 
{ 
    int radius = 100; 
    int strokeWidth = 10; 
    CGColorRef color = [UIColor redColor].CGColor; 
    int timeInSeconds = 5; 

    CGFloat startAngle = 0; 
    CGFloat endAngle = 0.33; 

    CAShapeLayer *circle = [CAShapeLayer layer]; 

    circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius) cornerRadius:radius].CGPath; 

    circle.position = CGPointMake(CGRectGetMidX(self.frame)-radius, CGRectGetMidY(self.frame)-radius); 

    circle.fillColor = [UIColor clearColor].CGColor; 
    circle.strokeColor = color; 
    circle.lineWidth = strokeWidth; 

    [self.layer addSublayer:circle]; 

    CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
    drawAnimation.duration   = timeInSeconds; 
    drawAnimation.repeatCount   = 1.0; 
    drawAnimation.removedOnCompletion = NO; 

    drawAnimation.fromValue = [NSNumber numberWithFloat:startAngle]; 
    drawAnimation.toValue = [NSNumber numberWithFloat:endAngle]; 

    drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 

    [circle addAnimation:drawAnimation forKey:@"drawCircleAnimation"]; 
} 

Respuesta

18

Cuando se aplica una animación a una capa, Core Animation crea una copia de la capa y anima a las propiedades de la copia. La capa original se llama la capa modelo y la copia se denomina capa presentación. Una animación nunca cambia las propiedades de la capa del modelo.

Ha intentado solucionar este problema mediante el establecimiento de removedOnCompletion a NO. También debería establecer el fillMode de la animación para que funcione, pero no es la forma correcta de animar una propiedad.

La forma correcta es cambiar la propiedad en su capa del modelo, a continuación, aplicar la animación.

// Change the model layer's property first. 
circle.strokeEnd = endAngle; 

// Then apply the animation. 
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
drawAnimation.duration   = timeInSeconds; 
drawAnimation.fromValue = [NSNumber numberWithFloat:startAngle]; 
drawAnimation.toValue = [NSNumber numberWithFloat:endAngle]; 
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
[circle addAnimation:drawAnimation forKey:@"drawCircleAnimation"]; 

Esto se explica en el Core Animation Essentials video de WWDC 2011. Recomiendo mucho verlo.

+0

¿Alguna idea sobre el progreso% (0 a 1) durante 'drawAnimation.duration'? – Jack

Cuestiones relacionadas