2010-10-25 8 views
13

Mam niestandardową CALayer (powiedzmy CircleLayer), zawierającą niestandardowe właściwości (promień i odcień). Warstwa renderuje się w swojej metodzie drawInContext :.Dlaczego animowanie niestandardowych właściwości CALayer powoduje, że inne właściwości są zerowe podczas animacji?

- (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); 
} 

Chcę promień być animatable więc już wdrożone

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

a animacja jest wykonywana tak:

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: pobiera nazywane zgodnie z oczekiwaniami podczas animacji aby przerysować okrąg, jednak odcień zostanie ustawiony na zero, gdy tylko animacja się rozpocznie i powróci do swojej pierwotnej wartości po zakończeniu animacji.

Doszedłem do wniosku, że jeśli chcę animować niestandardową właściwość i chcę, aby inne właściwości zachowały swoją wartość podczas animacji, muszę je również ożywić, co nie jest w ogóle wygodne.

Celem nie jest powiększanie/zmniejszanie koła, wiem, że mogę użyć do tego transformacji. Wystarczy tylko zilustrować prosty przykład problemu z animacją pojedynczej właściwości niestandardowej bez animowania wszystkich pozostałych.

Zrobiłem prosty projekt ilustrujący problem, który można znaleźć tutaj: Sample project illustrating the issue

Nie ma chyba coś nie dostać w jaki CoreAnimation działa, mam przeprowadzono intensywne poszukiwania, ale I” Utknąłem bez śladu. Ktokolwiek wie?

Odpowiedz

24

Jeśli dobrze zrozumiałem twoje pytanie, to wygląda tak. Po dodaniu animacji do obiektu CALayer tworzona jest tak zwana kopia prezentacji tej warstwy za pomocą initWithLayer:. Warstwa prezentacji zawiera rzeczywisty stan animacji dla każdej klatki animacji, natomiast warstwa oryginalna ma stan końcowy. Problem z animacją własnych właściwości polega na tym, że CALayer nie kopiuje ich wszystkich w initWithLayer:. Jeśli tak jest, należy zastąpić initWithLayer: i ustawić wszystkie właściwości potrzebne do animacji, czyli odcień i promień.

+1

Idealne masz rację, że rozwiązałeś problem! Wielkie dzięki :) – romrom

+0

Nie ma za co! – Costique

+0

To naprawdę przydatne. Zaoszczędził mi jeden dzień. – feihu

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

Animacja może wymagać wszystkich właściwości kontekstu, aby odpowiedzieć na odświeżenie.

+0

Próbowałem już tego i nie ma to żadnego efektu. – romrom

Powiązane problemy