by @mixiappwchr
以前コードをかかずにアニメーションを実装できるライブラリCanvasを紹介したのですが、
こちら簡単にかけるのですが、以下の点がちょっと残念でした。
- 複雑なアニメーションには対応できない.
- アニメーション完了時に処理をさせたり、他のUIのイベントと連携ができない
- クラス拡張してもプロパティを持たせたりすることができない。
なので自前で作ってみました。
Chains
このライブラリはInterfaceBuilder上で、色々なアニメーションを組み合わせて作ることができます。
特徴は、アニメーションの処理を複数つなぎ合わせて作成することができ,その処理の流れをInterfaceBuilderで決めることができます。
- 処理の記述がInterfaceBuilderで完結できます。
- UIViewの階層構造でアニメーション処理を記述することができるので色々なアニメーションを作り出せる。
- 拡張がしやすい。独自のプロパティを持たせたクラスの作成が可能
- UIイベントからの起動や終了イベント処理を実行可能
InterfaceBuilderで設定
すべての設定はInterfaceBuilder上で完結します。
使い方はCANAnimationクラスを継承したアニメーションをInterfaceBuilderに追加していきます。
追加の方法は、このクラス自体がUIViewを継承しているため、UIViewを追加後、Custom Classに使用したいアニメーションのクラスを記述します。
このクラス自体がは表示されることはありませんがアニメーションが開始されるのはこのViewの表示イベントをhookして起動します。
その後このクラスのtarget propertyにアニメーションさせたいViewを接続します。
ほかにもdelegateプロパティやstartChain:メソッドがIB上で見えるようになっていますが、これはあとで説明します
アニメーションを階層構造で作成する
このライブラリの最大の特徴は一つのアニメーションを実行するだけでなく、アニメーションを連結させて実行できる点です。
こちらの例のようにアニメーションクラスを子に追加していくとそのアニメーションを順番に実行させることが可能です。
これを素のコードで愚直に書くと
[UIView animateKeyframesWithDuration:self.duration/4 delay:self.delay options:0 animations:^{
// animation 1
} completion:^(BOOL finished) {
[UIView animateKeyframesWithDuration:self.duration/4 delay:0 options:0 animations:^{
// animation 2
} completion:^(BOOL finished) {
[UIView animateKeyframesWithDuration:self.duration/4 delay:0 options:0 animations:^{
// animation 3
} completion:^(BOOL finished) {
[UIView animateKeyframesWithDuration:self.duration/4 delay:0 options:0 animations:^{
// animation 4
} completion:^(BOOL finished) {
}];
}];
}];
}];
とpromiseでかけるライブラリなど使わない限りnest地獄になってしまいます。
これをInterfaceBuilderで書くことができ、なおかつ修正もInterfaceBuilderでぽちぽち変更できるので楽ちんです。
コードを記述する必要はありません。
他のUIのイベントと連携
先ほど例はviewが表示されるタイミングでアニメーションが開始されますが、ボタンを押したタイミングなど任意のタイミングで実行させたい場合もIB上で記述できます。
こちらのstartChain:というメソッドがアニメーション開始のメソッドですが、IBActionで設定しているので、IB上でイベント設定が可能です。
今回の例はアニメーションクラスはviewの外側に配置してstartChainメソッドをbuttonのイベントに設定してあります。
こうすることで,任意のタイミングでアニメーションを開始させることができます。
コードを記述する必要はありません。
ほかにもgestureに対応したアニメーションクラスなども用意しています。
完了イベントを設定
任意のタイミングでアニメーションを行ったら完了後に、処理を行う場合がほとんどかと思います。
その場合もIB上で設定が可能です。
処理を実行するクラスをdelegateに指定するのとcompletionプロパティに実行したいメソッドをStringで設定するとアニメーション完了に処理が呼ばれます
completionプロパティはUser Defined Runtime Attributesで設定します。
この場合はアニメーション完了後にViewControllerのendAnimationメソッドが呼ばれます.
処理の実行はこのアニメーションがすべて完了した時点でおこなわれるので、一番上の階層のanimationクラスにのみ設定すればokです。またアニメーションの途中にも設定することは可能です。
実際に見てみた方が早いので付属のサンプルを実際に動かしてみてもらえばと思います。
おわりに
UIViewを継承するという方法で、実現しているため実験的なライブラリになりましたが、コードレスで複雑なアニメーションにも対応できるのでなかなか使えるのではないかと思います。
このライブラリ自体は実はアニメーション専用ではなく、その他の処理にも使えるように作ってあります。
そのためアニメーション以外の処理もIBで実装するなども使えそうです。
Swiftの登場でObjective-Cを書かずにすむようになりますが、さらに一歩進んでコードレスで実装ができるようなライブラリにと思っています
ご意見やpull req大歓迎ですので触ってみていただければと思います。