パスに沿ってアニメーションさせる
Core Animationを用いると、UIViewのアニメーションと比較してより自由度の高いアニメーションを実現できます。たとえば、CAKeyframeAnimation に Core Graphics で描画したパスを渡すことで、円に沿ってアニメーションさせたり、放物線状にアニメーションさせたり、ハート形などの図形や、手書きの軌跡に沿ってアニメーションさせたりといったことが可能になります。
放物線状にアニメーションさせる
パスに沿ってアニメーションさせる方法のシンプルな事例として、サイドビューの2Dゲームのキャラ(例:マリオ)のジャンプのように、放物線状にアニメーションさせる場合の実装例を紹介します。
準備として、QuartzCore.framework をプロジェクトに追加し、ヘッダをインポートしておきます。
#import <QuartzCore/QuartzCore.h>
アニメーションの処理を下記のように実装します。
// CAKeyframeAnimationオブジェクトを生成 CAKeyframeAnimation *animation; animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; animation.fillMode = kCAFillModeForwards; animation.removedOnCompletion = NO; animation.duration = 1.0; // 放物線のパスを生成 CGFloat jumpHeight = 80.0; CGMutablePathRef curvedPath = CGPathCreateMutable(); CGPathMoveToPoint(curvedPath, NULL, kStartPos.x, kStartPos.y); CGPathAddCurveToPoint(curvedPath, NULL, kStartPos.x + jumpHeight/2, kStartPos.y - jumpHeight, kEndPos.x - jumpHeight/2, kStartPos.y - jumpHeight, kEndPos.x, kEndPos.y); // パスをCAKeyframeAnimationオブジェクトにセット animation.path = curvedPath; // パスを解放 CGPathRelease(curvedPath); // レイヤーにアニメーションを追加 [self.imageView.layer addAnimation:animation forKey:nil];
この実装のポイントは以下の2点です。
- CAKeyFrameAnimation で position プロパティをアニメーションさせるよう指定する
- Core Graphics で描画した放物線のパスを CAKeyframeAnimation の path プロパティにセットする
アニメーション完了時に処理を行う
アニメーション完了後に処理をさせたい場合は、CAAnimation のプロパティにある delegate を指定しておけば、
animation.delegate = self;
animationDidStop:finished: メソッドがアニメーション完了後に呼ばれるようになります。
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { NSLog(@"完了"); }
UIBezierPath オブジェクトをパスとして使用する
CAKeyframeAnimation の path プロパティの型は CGPathRef なので、UIBezierPath オブジェクトをパスとして使用したい場合は、UIBezierPath の CGPath プロパティから CGPathRef を取り出して使用します。
// CAKeyframeAnimationオブジェクトを生成 CAKeyframeAnimation *animation; animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; animation.fillMode = kCAFillModeForwards; animation.removedOnCompletion = NO; animation.duration = 1.0; // UIBezierPathで放物線のパスを生成 UIBezierPath *path = [UIBezierPath bezierPath]; CGFloat jumpHeight = 80.0; [path moveToPoint:kStartPos]; [path addCurveToPoint:kEndPos controlPoint1:CGPointMake(kStartPos.x + jumpHeight/2, kStartPos.y - jumpHeight) controlPoint2:CGPointMake(kEndPos.x - jumpHeight/2, kEndPos.y - jumpHeight)]; // パスをCAKeyframeAnimationオブジェクトにセット animation.path = path.CGPath; // レイヤーにアニメーションを追加 [self.imageView.layer addAnimation:animation forKey:nil];