Core Animation - 画面手前からフェードイン / 手前へフェードアウト

2010年11月3日水曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

[前回] Cocoaの日々: Core Animation - 画像が遠くから近づいてきてフェードアウトする [2]手直し

前回のコードを改良して、画面手前からフェードインするようなアニメーションを実装してみる。その逆に画面手前へフェードアウトさせる。そう、Dashboardのような動き。


サンプル実行


まずは動作から。こんな感じ。

 画面手前から現れたように拡大で始まる

徐々に縮小して目の前に現れる

最後は実寸大(100x75)表示

ボタンを押すと逆に実寸大の状態から徐々に拡大が始まり、画面の手前へフェードアウトする。


実装


前回の処理でアニメーションを行っていた箇所をメソッドとして切り出す。
#define DURATION 0.5
- (void)animateFadeInOut:(BOOL)flag
{
 CGFloat zPositionFrom = flag ? -1000 : 0;
 CGFloat zPositionTo = flag ? 0 : -1000;
 CGFloat opacityFrom = flag ? 0.25 : 1.0;
 CGFloat opacityTo = flag ? 1.0 : 0.25;

 CALayer* baseLayer = [self.view.layer.sublayers objectAtIndex:1];
 
 CABasicAnimation *animation;
 animation=[CABasicAnimation animationWithKeyPath:@"zPosition"];
 animation.fromValue=[NSNumber numberWithFloat:zPositionFrom];
 animation.toValue=[NSNumber numberWithFloat:zPositionTo];
 animation.duration=DURATION;
 animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
 animation.repeatCount = 1;
 animation.delegate = self;
 
 [baseLayer addAnimation:animation forKey:@"zPosition"];
 
 animation=[CABasicAnimation animationWithKeyPath:@"opacity"];
 animation.fromValue=[NSNumber numberWithFloat:opacityFrom];
 animation.toValue=[NSNumber numberWithFloat:opacityTo];
 animation.duration=DURATION;
 animation.repeatCount = 1;
 animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
 [baseLayer addAnimation:animation forKey:@"opacity"];  
 
}
フェードイン/フェードアウトによって値を逆転させている。フェードインの場合は zPosition -1000=>0, opacity 1.0=>0.25。zPositionが負値なので画面の手前から入ってくるような視覚効果となる。最後の 0 は原寸大の位置。フェードアウトの場合はちょうどその逆となる。


CAAnimation - デリゲート


CAAnimation にデリゲートを指定すると、アニメーションの開始と終了のタイミングで下記のメソッドが呼び出される。
- (void)animationDidStart:(CAAnimation *)theAnimation;
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag

今回はアニメーション終了時にフェートアウトの場合はベースレイヤーを隠している(hidden=YES)。ただこの場合一瞬原寸大で表示されてしまう。アニメーション終了後はアニメーション開始直前の状態に戻っていることがわかる。この一瞬の表示を隠すにはどうしたらよいものか。removedOnCompletion = NO としても駄目だった。

なお delegateプロパティは retain属性が付いている。
CAAnimation Class Reference より転載。
Important: The delegate object is retained by the receiver. This is a rare exception to the memory management rules described in Memory Management Programming Guide.
An instance of CAAnimation should not be set as a delegate of itself. Doing so (outside of a garbage-collected environment) will cause retain cycles.


CAAnimation - タイミング関数


アニメーションのタイミング(速度の緩急)は標準で数種類用意されている。

CAMediaTimingFunction Class Reference より転載
Predefined Timing Functions
These constants are used to specify one of the predefined timing functions used by functionWithName:.

NSString * const kCAMediaTimingFunctionLinear;
NSString * const kCAMediaTimingFunctionEaseIn;
NSString * const kCAMediaTimingFunctionEaseOut;
NSString * const kCAMediaTimingFunctionEaseInEaseOut;
NSString * const kCAMediaTimingFunctionDefault;
Linearは速度一定。EaseIn とは最初遅めで徐々に早くなる。EaseOut はその逆で最初早めで徐々に遅くなる。EaseInEaseOut は最初が遅めで徐々に加速、その後減速して最後は遅くなる。Defaultは Bézier timing function でパラメータが (0.25,0.1), (0.25,0.1) のケース。なお Default は Mac OS X は 10.6 から利用可能。

これらは +[CAMediaTimingFunction functionWithName:] でインスタンスを取得することができる。これを CAAnimation.timingFunctionへセットしてやればよい。
animation.timingFunction =
  [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];

Durationを短くする(0.25〜0.5秒)予定だが、その場合の視覚的効果はあまり差は感じられない。

[参考情報] CAMediaTimingFunction Class Reference


ソースコード


GitHub からどうぞ。

CoreAnimation3DSample2 at 2010-11-03 from xcatsan's iOS-Sample-Code - GitHub

Responses

Leave a Response

人気の投稿(過去 30日間)