運が良いことにこれまで複雑なViewのアニメーションやらの実装に遭遇することなく今まで仕事をして来れたので、「そういえばCALayer関連の基礎知識が抜けているなあ」と思ったので以下のDocumentを読んで、知らなかったことを書いていく。
Core AnimationはViewのコンテンツをbitmapに変換している
UIKitでは、描画するコンテンツとアニメーションの情報はCore AnimationというFrameworkで管理・操作している。 このFrameworkの内部で「Viewに表示するContentをbitmapとして保持して、指定の操作をbitmapに施し、実際にViewに表示する」ということをしている。
この時、bitmapについての情報を保持しているオブジェクトがCALayerであり、ユーザはこのCALayerに対して命令を出したりすることになる。(実際にはUIViewがCALayerのラッパーの役割をしており、簡単な操作なら直接CALayerを操作する必要はない)
このCALayerを介してbitmapを操作すると、Core Animationはグラフィック専用のHardwareを使って処理を行うらしく、たとえばViewを何十回も生成し直してアニメーションを作ったりするよりも、CALayerを介して「アニメーション時にパラメタの最終値と変化の流れ」を指定してあげる手法でアニメーションを作成する方が効率が良い。
CALayerは実際は3次元空間を想定している
座標操作時、CALayerでは以上のような行列式で(x, y, z)の値を変化させている。普段意識していなかったが、画像のようにz座標に対しての変換もCALayerでは想定している。
目的別の3つのLayer setがある
Core Animationで3つのLayer setを保持している。
- model layer tree
- アニメーションの終着点を保持しているLayer。ユーザが「このようなアニメーションをしたい」と思った時、実際アニメーションに利用するパラメタの最終値を設定することになるが、その値を保持しているLayer set。
- presentation tree
- アニメーション途中におけるパラメタを持っているLayer set。(一応このアニメーション途中のパラメタは修正できるようだが、するべきでないと書かれている)
- render tree
- 実際にアニメーションが行われているLayer set。(このLayer setはCore Animation内でPrivateになっておりユーザから値を修正することはできない)
なぜ3層に分かれているのか、という記述が特になかったが、単純に「ユーザがアニメーションの設定をする層」「アニメーション中のパラメタを参照出来る層」「Core Animationで実際に操作し、ユーザに直にいじらせたくない層」で役割分担をした結果ではと思う。
感想
思えば、UIViewの「Viewのカドを丸くしたい」みたいな時にしかCALayerを直接いじるみたいなことはしてこなかった気がする。
また、CALayerが3次元空間を想定しているみたいなので、Paypayアプリのカードのフリップアニメーションも簡単に実装できるのかもなと思ったので、こちらはちょっとやってみたい。
