Help us understand the problem. What is going on with this article?

Core Animationのレイヤ

More than 5 years have passed since last update.

Core Animationプログラミングガイド(PDF)

「CALayerって角丸以外に使ったこと無いけどなんか他に機能あるんじゃね?」という疑問を解決するためにを読んだ。
今回は前半のレイヤについてのところをかなりざっくりまとめる。

Core Animation

  • グラフィックス描画やアニメーションの基盤機能
    • Viewに置き換わるものではなく、視覚要素に動きを加えるための汎用システム
    • 低レイヤから、グラフィックスハードウェア→OpenGL, Core Graphics→Core Animation→UIKit, AppKit
    • アプリケーションのコンテンツを画像の形に合成してハードウェア上で操作する
  • iOS, OS Xで利用可能(使える機能に違いはあるけども)
  • その心臓部がレイヤオブジェクトとのこと

レイヤオブジェクト

  • 3次元空間内に置かれた2次元の平面
  • コンテンツはビットマップでキャッシュしてる
    • バッキングストア
  • 階層化して管理できる
    • addSublayer, removeFromSuperLayer...etc

レイヤオブジェクトの描画モデル

  • レイヤオブジェクトのプロパティを変更すると、ビットマップが更新されるわけではなく、
  • レイヤオブジェクトが持っている状態情報が更新される
  • ビットマップと状態情報をハードウェアに渡して、ハードウェアが描画するという感じ

レイヤのコンテンツを設定する方法

3つの方法がある

  • contentsプロパティに設定
  • CALayerDelegateを実装
  • CALayerのサブクラスでメソッドをoverride

contentsプロパティに設定

contentsプロパティにはCGImageRef型が渡せる

let aImage = UIImage(named: "image.jpg")
let aLayer = CALayer()
aLayer.contents = aImage.CGImage

CALayerDelegateを実装

  • func displayLayer(_ layer: CALayer!))でcontentsプロパティに代入か
  • func drawLayer(_ layer: CALayer!, inContext ctx: CGContext!)で、ビットマップを設定するか

ビットマップ設定はCore Graphicsの話になると思うのでまた今度調べる。

CALayerのドキュメント

In iOS, if the layer is associated with a UIView object, this property must be set to the view that owns the layer.

と書いており、UIViewとそのサブクラスのlayer.contetnsにはdelegateからは渡せないっぽい。

そもそもimport QuartzCoreしても、CALayerDelegateを補完してくれず、
いろいろ試してみたが結局できなかった。。だれかやり方教えてください。

CALayerのサブクラスでメソッドをoverride

  • func display()でcontentsプロパティに設定する
  • func drawInContext(_ ctx: CGContext!)でビットマップ設定

設定できるプロパティ

// 透過度
aLayer.opacity = 0.0

// 角丸
aLayer.masksToBounds = true
aLayer.cornerRadius = 5.0

// Z軸180度回転
aLayer.transform = CATransform3DRotate(aLayer.transform, CGFloat(M_PI), 0, 0, 1)

// 拡大・縮小
// XY2倍拡大
aLayer.transform = CATransform3DScale(aLayer.transform, 2.0, 2.0, 0.0)

// 移動
// X方向に100, Y方向に100移動
aLayer.transform = CATransform3DTranslate(aLayer.transform, 2.0, 2.0, 0.0)

暗黙のアニメーション

CALayerは何も設定しなくてもアニメーションが適用される

var hidden = false

// 勝手にフェードイン・アウトする
@IBAction func toggleOpacity (sender: AnyObject) {
  aLayer.opacity = hidden ? 1.0 : 0.0
  hidden = !hidden
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away