[iOS] たった2行でTweenアニメーションを実装できるコードを公開。

先日、こんな記事が話題になっていましたね。
職人が教える!iOSアプリ開発で使いこなしたいとっておきのOSS
第1回 様々なアニメーションを実現するiOSアプリ用トゥイーンライブラリ3種を比較!

実はTweenという言葉すら初耳だった程度の知識なのですが、この記事を読んでサンプルコードをいじってみました。
ですが、正直どれも使い方が複雑で使いづらいなぁ。。という印象でどうにかならないものかな?と。
もちろん、本格的なTweenを実現するには多少複雑になってしまうのは分かるのですが、実際に使うとなるとそこまでの機能は必要ない場合の方が多いんじゃない?ってのが今回のコードを用意したきっかけ。

そこで、上記記事であげられていたライブラリを参考に、もっと簡単に使えるTweenアニメーション用コードを書いてみましたので、ご参考まで。
ツッコミ大歓迎です!


今回のコードを使えば、アニメーションしたい所で例えばこんな風に書くだけでTween付きで実行されます。

 
CFTimeInterval duratin = 1.0f;
 
// Tweenアニメーションを作成
CAAnimation *anim = PBTweenAnimationTypePosition(FROM_CENTER, TO_CENTER, duratin, PBTweenFunctionElasticEaseOut);
[_animLayer addAnimation:anim forKey:nil];
 

PBAnimationTypeXxxx()の内部ではCAKeyframeAnimationを生成して、anim.valuesにTweenの計算式を元に算出した値を入れています。
AnimationTypeは、Opacity(フェード)、Scale(拡大縮小)、Position(移動)、Size(リサイズ)、Frame(移動 + リサイズ)、2DRotate(z軸の回転)、3DRotate(x, y軸のパース付き回転)の7種類です。
ちなみにPBTweenFunctionの定義はこんな感じ。

  
typedef enum {
    PBTweenFunctionNon              = 00,   // Liner
    
    PBTweenFunctionQuadEaseIn       = 10,
    PBTweenFunctionQuadEaseOut      = 11,
    PBTweenFunctionQuadEaseInOut    = 12,
    
    PBTweenFunctionCubicEaseIn      = 20,
    PBTweenFunctionCubicEaseOut     = 21,
    PBTweenFunctionCubicEaseInOut   = 22,
    
    PBTweenFunctionQuartEaseIn      = 30,
    PBTweenFunctionQuartEaseOut     = 31,
    PBTweenFunctionQuartEaseInOut   = 32,
    
    PBTweenFunctionQuintEaseIn      = 40,
    PBTweenFunctionQuintEaseOut     = 41,
    PBTweenFunctionQuintEaseInOut   = 42,
    
    PBTweenFunctionSineEaseIn       = 50,
    PBTweenFunctionSineEaseOut      = 51,
    PBTweenFunctionSineEaseInOut    = 52,
    
    PBTweenFunctionExpoEaseIn       = 60,
    PBTweenFunctionExpoEaseOut      = 61,
    PBTweenFunctionExpoEaseInOut    = 62,
    
    PBTweenFunctionCircEaseIn       = 70,
    PBTweenFunctionCircEaseOut      = 71,
    PBTweenFunctionCircEaseInOut    = 72,
    
    PBTweenFunctionElasticEaseIn    = 80,
    PBTweenFunctionElasticEaseOut   = 81,
    PBTweenFunctionElasticEaseInOut = 82,
    
    PBTweenFunctionBackEaseIn       = 90,
    PBTweenFunctionBackEaseOut      = 91,
    PBTweenFunctionBackEaseInOut    = 92,
    
    PBTweenFunctionBounceEaseIn     = 100,
    PBTweenFunctionBounceEaseOut    = 101,
    PBTweenFunctionBounceEaseInOut  = 102,
} PBTweenFunction;
 

右の数字は、内部でTweenを判別しやすくするために指定しています。

Elastic、Back、Bounce以外のTweenの速度変化についてはこちらが詳しいです。
[NodeBox]イージング処理の計算式 -強火で進め

ちなみに僕のようにTweenを知らなかった方のために、残りの3つを簡単に説明しときますね。(分かりやすくするために『位置移動+EaseOut』を条件にしています。)

  • Elastic:ゴムのような弾力で終点を超えた位置から振り幅を小さくしつつ複数回バウンド。
  • Back:低反発まくらの様な反発で一度終点を超えてゆっくり終点へ戻る。
  • Bounce:固めの球体がブロック壁に当たったような弾力で終点を超えずに複数回バウンド。

また、Tween計算の元になっている“Robert Penner’s Easing Equations”では、ひとつのアニメーションを経過時間ごとに複数に分割してTweenを実現しているのですが、その分割された各タイミング毎のvalue(アニメーション後の値)を計算する為に以下が必要になります。

  • 経過時間(current time)
  • アニメーションの初期値(beginning value)
  • 初期値とアニメーション終了時の値の差(change in value)
  • トータルの時間(duration)

これに加えて、Elastic、Backには他のTweenには無いオプションの値が入れられるようになっています。(※ 説明部分は解釈が間違ってるかも。。)

    Elastic

  • amplitude(Default: 0.0)
    振幅の大きさ
  • period(Default: 0.0)
    値が大きいほど反発を吸収する
    Back

  • overshoot(Default: 1.70158 = 10%)
    始点/終点を超える量

(Bounceにも基本速度(?)のオプションがあるようですが、こちらは実装していません。)
これらのオプションを利用するために以下のような関数も用意しています。

 
CAKeyframeAnimation *PBTweenAnimationTypePositionWithOption
                        (CGPoint startPosition, CGPoint endPosition, 
                         CFTimeInterval duration, PBTweenFunction function, 
                         double amplitude, double period, double overshoot);
 

クラス化していないこともあって、あまりスマートではないのですが関数名に”withOption”とついたものを利用します。
最後の3つの引数がオプションの値になりますが、PBTweenFunctionがElastic、Back以外の場合は値は無視されます。
また、Elasticならovershoot、Backならamplitudeとperiodがそれぞれ無視されるのでそれらは0.0とかしておけばOKです。

もし、もう少し複雑なアニメーションをしたい場合は、CATransactionと組み合わせたり、以下のように複数のTween済みアニメーションを組み合わせて使うと色んなバリエーションが出せると思います。

 
CFTimeInterval duratin = 1.0f;
PBTweenFunction function = PBTweenFunctionQuintEaseInOut;

// 移動アニメーション
CAAnimation *moveAnim = PBTweenAnimationTypePosition(FROM_CENTER, TO_CENTER, duratin, function);
// 回転
CAAnimation *rotateAnim = PBTweenAnimationType2DRotate(0.0f, -360.0f, duratin, function);
// リサイズ(バウンスする)
CAAnimation *scaleAnim = PBTweenAnimationTypeScale(1.0f, 3.0f, duratin, PBTweenFunctionBounceEaseOut);
    
// アニメーションをグループ化(移動回転しながら拡大してバウンス)
CAAnimationGroup *animGroup = [CAAnimationGroup animation];
animGroup.animations = [NSArray arrayWithObjects:moveAnim, rotateAnim, scaleAnim, nil];
    
[_animLayer addAnimation:animGroup forKey:nil];
  

もちろん、一度にあまり多くのCAAnimationオブジェクトを生成するとアニメーションの開始が遅れたりすることもあるので、その辺は容量、用法を守ってお使いくださいませ<(_ _;)>

実際のコード(PBTweenDemo)は以下のGithubにあげていますので、気になった方は是非使ってみて感想を@Jacminik宛にMentionもらえると嬉しいです。
https://github.com/Jacminik/PBTweenAnimation

では、また!

P.S.
Gumroadも考えたのですが凄く単純な実装なのでやめました(^〜^;)

広告

[iOS] たった2行でTweenアニメーションを実装できるコードを公開。」への3件のフィードバック

  1. ピンバック: [朝刊] iPhone アプリ開発の入門情報がまとまっています。 - AppBank

  2. ピンバック: [iOS] たった2行でTweenアニメーションを実装できるコードを公開。 | Everything was born from Love | WordBuff.in

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中