ブロックチェーン・AI・システム開発の株式会社INDETAIL

ios ViewとLayerの関係

2014.04.28
なめ橋

こんにちは。
なめ橋です。

GWですね。
毎年来ているものですが、「ゴールデンウィーク」という名前の由来を調べてみました。
wikipediaによると、元々は、映画会社の取締役の方が番宣用の言葉として使い始めたのが由来なんだそうです。
「みんなで映画館に行きましょう!」ということですね。

ViewとLayer

今回はUIViewとCALayerの関係についてです。
今まで、Animationを取り上げていろいろ記事を書いてきましたが、「そもそもLayerって何?」という状態だったため、調べてみました。
まず、それぞれについて簡単に整理します。

UIView

画面に対して、描画を行うクラスです。
その他にも画面タッチに関するイベントや、レスポンダチェーンなどを取り扱います。

CALayer

Veiwに描画する内容を管理するモデルオブジェクト(のようなもの)です。
ジオメトリ、コンテンツ、視覚属性などを管理しますが、独自の「外観」を定義するものではありません。また、CALayerはCoreAnimationと密な関係にあり、作成したアニメーションはすべてLayer内に存在する3つのオブジェクトが管理いたします。

つまり、Viewは実際の描画やイベント処理などを担当し、描画する内容はLayerが管理するということです。
CALayerに関してはViewと比べて少々複雑なので、もう少し詳しく見てみましょう。

CALayer

CALayerのメインの役割は、Viewに表示する内容を管理したり、アニメーションオブジェクトを適用させる器として機能します。
基本的に画面に対しての描画はViewが担当しますが、アニメーションを行う場合のみ描画はViewではなくGPUが担当します。

「なぜ、アニメーションを行う場合はGPUが描画担当なのか」というと、
Viewベースでの描画の場合、drawRectメソッドを呼び出し、Layerに保持されているパラメーターに基づいて描画を行います。
しかし、この方法でアニメーションを描画した場合、主スレッドのCPUを使うため負荷が高くなり、思った通りに描画されなかったり、他のプロセスに影響を与える可能性があります。

一方GPUベースの場合、描画をハードウェアが直接担当するため、描画が早くなります。
ただし、GPUが直接描画を行うためにはBitMap形式でのデータが必要です。
そのため、Layerはコンテンツを管理する際、コンテンツをBitMap形式でキャッシュ化し、管理しています。
(これをバッキングストアと言います。)

また、アニメーションを行う際、レイヤオブジェクトは3種類に分類されます。

  • モデルレイヤ:アニメーションの終了点に関する情報を保持します。
    レイヤのプロパティを変更する際にはこのオブジェクトを操作することになります。

  • プレゼンテーションレイヤ:実行中のアニメーションにおける現在地を表します。
    つまり、アニメーションの最中に現在アニメーションを行っているオブジェクトがどの状態にあるか(例:どのポジションにいるか等)を管理します。

  • 描画レイヤ:プレゼンテーションレイヤの値を使用して、別スレッドにて描画を担当するレイヤです。このオブジェクトはCoreAnimationが内部的に使用するため、通常は触れることはありません。

<

p>ここまでのことを図示したのが下記の図になります。

layer

また、iOSで使用するViewオブジェクトはすべて自動的にレイヤが生成されます。これを自動レイヤ付きビュー(layer-backed view)と言います。
一方、Viewを持たないレイヤをスタンドアローンレイヤといい、これらを描画するためには、他のViewを持つLayerに埋め込んで使います。

例えばこんな感じですね。

これでLayerが描画されるのは、addしたself.view.layerがViewを持っているLayerのため、描画担当のViewが存在する為なんですね。
これが可能なのは、LayerもViewと同様に、階層化して管理することができる為です。
そのため、ViewとLayerの関係は常に1:1の関係ではなく、1:nの関係となります。

 

如何でしょうか?
今回はiOSの根幹に近い部分を取り上げさせていただきました。
このような根深い箇所を理解すると、実際にコードを見た時、勉強した成果を実感できるのでうれしいですね。

なめ橋

2013年4月に入社。 最近ようやくiOSの開発に慣れてきた新人のエンジニアです。 髪が長くなるとなめこに似ているといわれます。

「いいね」ボタンを押すと、最新情報をすぐに確認できます。