iphone - 繰り返し - カスタムCALayerプロパティをアニメーション化すると、アニメーション中に他のプロパティがnilになるのはなぜですか?




uiviewanimationoptions (2)

カスタムプロパティ(半径と色合い)を含むカスタムCALayer(CircleLayer)があります。 レイヤーは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); 
}

半径をアニメーション化して実装してもらいたい

+ (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:円を再描画するためにアニメーション中に期待通りに呼び出されますが、アニメーションが開始されるとすぐに色合いはnilに設定され、アニメーションが終了すると元の値に戻ります。

私は、カスタムプロパティをアニメーション化し、アニメーション中に他のプロパティに値を保持したい場合は、アニメーション化する必要があります。これは便利ではないことがわかります。

目的は円を拡大/縮小することではなく、私はこれを変換することができます。 単純な例では、他のすべてのアニメートを行わずに単一のカスタムプロパティをアニメートするという問題を説明するだけです。

私はこの問題を説明する簡単なプロジェクトを作成しました。ここで見つけることができます: 問題を示すサンプルプロジェクト

おそらく、CoreAnimationの仕組みに慣れていないものがあります。私は集中的な検索を行ってきましたが、私はヒントを得られません。 誰でも知っていますか?


私があなたの質問を正しく理解していれば、このようになります。 アニメーションをCALayerに追加すると、 initWithLayer:を使用して、そのレイヤのいわゆるプレゼンテーションコピーがinitWithLayer: 。 プレゼンテーションレイヤは、各アニメーションフレームの実際のアニメーション状態を含み、元のレイヤは最終状態を有する。 独自のプロパティをアニメーション化する際の問題は、CALayerがinitWithLayer:それらをすべてコピーしないことinitWithLayer: 。 その場合、 initWithLayer:をオーバーライドして、アニメーションに必要なすべてのプロパティ、つまり色合いと半径を設定する必要があります。


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

アニメーションでは、リフレッシュに応答するためにコンテキストのすべてのプロパティが必要になる場合があります。





null