web-dev-qa-db-ja.com

CALayerの不透明度アニメーション

一種の「派手な」効果を与えるCALayerアニメーションを作成したいと思います。そのために、「不透明度」プロパティをアニメーション化しようとしていますが、問題は、どこから開始し、どのように実行するかがわからないことです。

アニメーションの図解は次のとおりです。

opacity
   |    ___
1  |   |   |
   |   |   |    * repeatCount
0  |___|   |_ . . .
   -------------------------> time
    |______|
    duration

不透明度は0から始まり、1にアニメーション化され、次に再び0にアニメーション化されます(この0から1から0へのアニメーションには、継続時間に等しい秒数がかかります)。次に、このプロセスが「repeatCount」回繰り返されます。

コードの背景は次のとおりです。

float duration = ...; // 0.2 secs, 1 sec, 3 secs, etc
int repeactCount = ...; // 1, 2, 5, 6, ect

CALayer* layer = ...; // I have a CALayer from another part of the code
layer.opacity = 0;

// Animation here

done = YES; // IN THE END of the animation set this ivar to yes

これを達成するための最良の方法は何ですか?私はこれまでCALayersを使用したことがないので、アニメーションシステムがどのように機能するかを学ぶ良い機会でもあります。ちなみに、私はドキュメントを検索し、1つまたは2つの簡単なアニメーションを追加する方法を理解していますが、この特定のアニメーションを実行する方法がわかりません。

19
Alex

これを実現する最良の方法は、CABasicAnimationのインスタンスを作成し、それをレイヤーに追加することにより、明示的なアニメーション( ガイド を参照)を使用することです。

コードは次のようになります。

CABasicAnimation *flash = [CABasicAnimation animationWithKeyPath:@"opacity"];
flash.fromValue = [NSNumber numberWithFloat:0.0];
flash.toValue = [NSNumber numberWithFloat:1.0];
flash.duration = 1.0;        // 1 second
flash.autoreverses = YES;    // Back
flash.repeatCount = 3;       // Or whatever

[layer addAnimation:flash forKey:@"flashAnimation"];

アニメーションがいつ完了するかを知りたい場合は、デリゲートを設定してanimationDidStop:finished:メソッドを実装できますが、すべてのコードを同じ場所に配置できるようにするため、完了ブロックを使用することをお勧めします。 iOS4またはOSX用に作成している場合は、優れた CAAnimationBlocks カテゴリを使用してこれを実現できます。

45
trojanfoe

Trojanfoeの答えは素晴らしいです。 「タイムライン」(フェードアウトにかかる時間、待機する時間、フェードインにかかる時間など)をより細かく制御したい場合は、追加したいと思います。複数のCABasicAnimationをCAAnimationGroupに結合したいとします。

このトピックに関する私の本の章を読むことをお勧めします。その最後の部分は、CAAnimationとその子孫に関するチュートリアルを構成しています。

http://www.apeth.com/iOSBook/ch17.html#_core_animation

私の議論はiOSに向けられていることに注意してください。 Mac OS Xでは、その場所にいる場合、ビュー/レイヤーアーキテクチャは少し異なりますが、CAAnimationについての説明は正しいです。

2
matt