3

CABasicAnimation を使用して CALayer を回転させていますが、正常に動作します。問題は、同じレイヤーを回転しようとすると、回転する前に元の位置に戻ることです。私の予想される出力は、次のローテーションでは、終了した場所から開始する必要があるということです。これが私のコードです:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.fromValue         = 0;
animation.toValue           = [NSNumber numberWithFloat:3.0];
animation.duration          = 3.0;
animation.timingFunction    = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.removedOnCompletion = NO;
animation.fillMode          = kCAFillModeForwards;
animation.autoreverses      = NO;
[calayer addAnimation:animation forKey:@"rotate"];

私のコードに欠けているものはありますか? ありがとう

4

2 に答える 2

16

何が起こっているかというと、プレゼンテーション レイヤーにアニメーションが表示されているということです。ただし、レイヤーの実際の位置は更新されません。したがって、アニメーションが終了すると、レイヤーは変更されていないため、元の状態で表示されます。

「コア アニメーション レンダリング アーキテクチャ」を読むことは本当に価値があります。そうしないと、非常に混乱する可能性があります。

CABasicAnimationこれを修正するには、次のようにデリゲートを設定します。

[animation setDelegate:self];

次に、アニメーションの完了時に必要なターゲット プロパティを設定するメソッドを作成します。さて、ここが紛らわしい部分です。animationDidStartではない上でこれを行う必要がありますanimationDidStop。そうしないと、プレゼンテーション レイヤーのアニメーションが終了calayerし、元の位置でちらつきが発生し、アニメーションなしでターゲット位置にジャンプします。試してみるとanimationDidStop、私の言いたいことがわかるでしょう。

あまり混乱しないことを願っています!

- (void)animationDidStart:(CAAnimation *)theAnimation
{
    [calayer setWhateverPropertiesExpected];
}

編集:

私は後で、Apple がこれを行うためのより良い方法を推奨していることを発見しました。

Oleg Begemannは、彼のブログ投稿Prevent Layers from Snapping Back to Original Values When Using Explicit CAAnimationsで適切なテクニックについて適切に説明しています。

基本的に、アニメーションを開始する前に、レイヤーの現在の値、つまり元の値をメモします。

// Save the original value
CGFloat originalY = layer.position.y;

次に、レイヤーのモデルにtoValueを設定します。したがって、レイヤ モデルには、実行しようとしているアニメーションの最終的な値があります

// Change the model value
layer.position = CGPointMake(layer.position.x, 300.0);

次に、上でメモした元の値であるアニメーションfromValueを使用してアニメーションを設定します。

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.y"];

// Now specify the fromValue for the animation because
// the current model value is already the correct toValue
animation.fromValue = @(originalY);
animation.duration = 1.0;

// Use the name of the animated property as key
// to override the implicit animation
[layer addAnimation:animation forKey:@"position"];

上記の編集中のコードは、明確にするために Ole Begemann のブログからコピー/貼り付けされたものであることに注意してください

于 2011-10-07T17:37:10.107 に答える
1

アニメーションを終了位置から開始する場合は、fromValueプロパティをCALayerの現在の回転に設定します。

その値を取得するのは難しいですが、この SO 投稿はその方法を示しています: https://stackoverflow.com/a/6706604/1072846

于 2012-09-20T14:35:00.793 に答える