2010-10-25 49 views
13

我有一個自定義CALayer(說CircleLayer),包含自定義屬性(半徑和色調)。該圖層在drawInContext:方法中呈現自身。爲什麼動畫自定義CALayer屬性導致其他屬性在動畫過程中爲零?

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

我想半徑是動畫,所以我已經實現

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

而且動畫像這樣進行:

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:在動畫過程中如預期被調用重新繪製圓形,但是一旦動畫開始,色彩設置爲零,並在動畫結束時恢復到其原始值。

我已經得出結論,如果我想動畫一個自定義屬性,並希望其他屬性在動畫期間保持其值,我必須爲它們設置動畫效果,我覺得這不是很方便。

目的不是增長/縮小一個圓圈,我知道我可以使用轉換爲此。只是用一個簡單的例子來說明動畫化單個自定義屬性的問題,而不必爲所有其他動畫製作動畫。

我做了說明這個問題,你可以在這裏找到一個簡單的項目: Sample project illustrating the issue

有可能是什麼我沒上CoreAnimation如何工作搞定了,我已經進行了深入的搜索,但我米堅持不了。有誰知道?

回答

24

如果我正確理解你的問題,它就是這樣。將動畫添加到CALayer時,它會使用initWithLayer:創建該圖層的所謂演示文稿副本。表示層包含每個動畫幀的實際動畫狀態,而原始層具有最終狀態。動畫您自己的屬性的問題是CALayer不會將它們全部複製到initWithLayer:。如果這是您的情況,您應該重寫initWithLayer:並設置動畫所需的所有屬性,即色調和半徑。

+1

完美你是對的,解決了這個問題!非常感謝:) – romrom 2010-10-25 16:30:21

+0

不客氣! – Costique 2010-10-25 16:31:37

+0

這真的很有用。它爲我節省了一天的時間。 – feihu 2015-05-19 02:36:06

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

動畫可能需要上下文的所有屬性才能響應刷新。

+0

我已經試過了,它沒有效果。 – romrom 2010-10-25 16:21:12