iphone animation properties calayer null
Proyecto de ejemplo que ilustra el problema

iphone - ¿Por qué animar propiedades CALayer personalizadas hace que otras propiedades sean nulas durante la animación?



animation properties (2)

Si entendí tu pregunta correctamente, es así. Cuando agrega una animación a un CALayer, crea una llamada copia de presentación de esa capa usando initWithLayer: La capa de presentación contiene el estado animado real de cada cuadro de animación, mientras que la capa original tiene el estado final. El problema con la animación de sus propias propiedades es que CALayer no las copia todas en initWithLayer: Si ese es su caso, debe anular initWithLayer: y configurar todas las propiedades que necesita para la animación, es decir, tanto el tinte como el radio.

Tengo un CALayer personalizado (por ejemplo, CircleLayer), que contiene propiedades personalizadas (radio y tinte). La capa se representa en su método drawInContext:

- (void)drawInContext:(CGContextRef)ctx { NSLog(@"Drawing layer, tint is %@, radius is %@", self.tint, self.radius); CGPoint centerPoint = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2); CGContextMoveToPoint(ctx, centerPoint.x, centerPoint.y); CGContextAddArc(ctx, centerPoint.x, centerPoint.y, [self.radius doubleValue], radians(0), radians(360), 0); CGContextClosePath(ctx); /* Filling it */ CGContextSetFillColorWithColor(ctx, self.tint.CGColor); CGContextFillPath(ctx); }

Quiero que el radio sea animable, así que lo he implementado.

+ (BOOL)needsDisplayForKey:(NSString *)key { if ([key isEqualToString:@"radius"]) { return YES; } return [super needsDisplayForKey:key]; }

Y la animación se realiza así:

CABasicAnimation *theAnimation=[CABasicAnimation animationWithKeyPath:@"radius"]; theAnimation.duration=2.0; theAnimation.fromValue=[NSNumber numberWithDouble:100.0]; theAnimation.toValue=[NSNumber numberWithDouble:50.0]; theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [circleLayer addAnimation:theAnimation forKey:@"animateRadius"]; circleLayer.radius = [NSNumber numberWithDouble:50.0];

drawInContext: se llama de la forma esperada durante la animación para volver a dibujar el círculo, sin embargo, el tinte se establece en nulo tan pronto como comienza la animación y vuelve a su valor original cuando la animación termina.

Llegué a la conclusión de que si quiero animar una propiedad personalizada y quiero que otras propiedades mantengan su valor durante la animación, también tengo que animarlas, lo que no me resulta conveniente en absoluto.

El propósito no es aumentar / reducir un círculo, sé que puedo usar la transformación para esto. Es solo para ilustrar con un ejemplo simple el problema de animar una propiedad personalizada única sin tener que animar a todas las demás.

He realizado un proyecto simple que ilustra el problema, que puede encontrar aquí: Proyecto de ejemplo que ilustra el problema

Probablemente hay algo que no entendí sobre cómo funciona CoreAnimation, realicé una búsqueda intensiva pero no me di cuenta. ¿Alguien sabe?


+ (BOOL)needsDisplayForKey:(NSString *)key { if ([key isEqualToString:@"radius"] || [key isEqualToString:@"tint"]) { return YES; } return [super needsDisplayForKey:key]; }

La animación puede requerir que todas las propiedades del contexto respondan a una actualización.