CALayer知识梳理

关于Core Animation API怎么使用的文章很多,例如下面这些都写的非常好。

ojbc中国#12动画

我这篇文章主要解释一下动画的本质是什么,不涉及太多具体使用。

iOS动画的本质

CALayer是动画产生作用的地方,CALayer是什么鬼呢?看名字像是个Photoshop中的那种图层的概念。在iOS中,一个Layer『本文中的Layer指的是CALayer或它的子类』对象看起来就像一个在3D空间的2D图像显示,为什么说在3D空间呢?因为你可以通过矩阵运算对这个Layer画面进行三纬的翻转,平移、缩放等当然也都不在话下。Layer是你通过Core Animation做的所有事情的核心。

与视图一样,Layer管理着几何信息(位置和大小等)、内容和与显示相关的属性信息。

与视图不同的是,Layer没有定义他自己的外观。

一个Layer仅仅是管理这它的位图(bitmap)相关的状态信息,这个位图可以是它的delegate view的drawRect:方法绘制的,或者你直接设置的一个静态图片信息。

基于这个原因,在app中使用大多数layer都可以被认定是模型(model)对象,因为他们主要是管理数据。这个概念比较重要,因为它影响这动画的行为。你务必要理解,当把动画添加到一个layer时,是不直接修改model的属性的。

取而代之的是,Core Animation维护了两个平行的layer层次结构,model layer tree(模型层树)和presentation layer tree(表示层树)。前者为model的实际属性值,后者为动画正在发生时刻的当前属性近似值(因为动画的属性插值为离散的)。如果要获取某个触发动画的属性在动画过程中的任意值,你需要通过presentation layer的属性获取。

事实上还有一个rendering tree,动画的实际执行,由于是Core Animation私有,这里不解释。

基于Layer的绘图模型

说到Layer的绘图,实际上你app中的大多数layers不会做任何内容绘制的,取而代之的是捕捉你的app提供给他的内容(UIView绘制或者设置contents),然后将它们缓存为位图(bitmap),就是我们常提到的视图的图像后备存储(backing store)。当你随后改变了layer的某个属性,实际就是修改了layer model的状态信息,如果这个动作触发了动画,那么Core Animation会将layer的位图和新的状态信息传给图像处理硬件(通常指GPU),它会根据新的状态信息渲染位图。通过GPU直接操作位图要比使用CPU通过软件绘制要快非常多。

我们可以看到基于Layer的绘图实质上是GPU对静态位图计算操作,这与传统的基于视图的图像绘制有非常显著的差异。

基于视图的绘制,视图的属性变化往往带来的结果是使用不同的参数去调用UIView的drawRect:方法来重绘视图的内容。通过这个方式绘制是非常昂贵的,因为它是使用主线程的CPU来完成的。

Core Animation尽可能的通过硬件对位图的操作来达到相同或者近似的结果来避免上述问题。

你能通过3种方式给Layer提供content内容:

  • 给Layer的contents属性直接提供一张图片。(适合于内容几乎不变的Layer)
  • 给Layer指定一个delegate,让delegate来绘制Layer的内容。(适用于内容会周期性变化且内容可以由外部提供的Layer,就像UIView的root layer)
  • 定义一个子Layer继承于CALayer或者它的子类,然后重写它的绘图方法,让Layer自己为它自己提供内容。

基于Layer的动画

Layer的真实数据和状态信息是与在屏幕上的视觉展示相剥离的。就是说Core Animation维护了两个平行的Layer层次结构,model layer tree和presentation layer tree。这种机制使Core Animation能够在新旧状态间进行插值和动画过渡。

在动画的过程中,Core Animation通过硬件为你完成动画过程中每一帧图像的绘制。而你所需要做的仅仅是告诉它动画的开始和结束状态,其他的都交给Core Animation去完成。当然如果你开心,你也可以指定一些动画参数,例如动画时间、插值计算的timeFunction等参数。

Layer的几何属性

layer_geometry.png

主要涉及3个属性:bounds、position和anchorPoint。

bounds:与UIView类似,origin属性影响子Layers,(0,0)为子Layers布局的坐标参考原点。
size为大小。

anchorPoint:定义了一个锚点,类似被图钉在墙上的一张纸,纸的旋转是以它为中心的。值为相对自身几何体系。值范围为0到1,默认在中心处(0.5,0.5)

position:anchorPoint相对与layer的坐标系的坐标(与anchorPoint实质是同一个点,参考不同坐标系)。

注意:UIView的frame就是简单的读取至它的root layer。

Layer与View的关系

从我们上文的介绍,我们可以认识到。Layer为view相对于为提供了基础设施服务,具体来说就是Layer让view能以较高的帧数和效率对其内容进行重绘和动画。

但是,Layer有很多事不能做,Layer不能处理事件、绘制内容、参与响应链和很多其他事情。因此,你的app至少得有一个或多个view来处理这类交互。

在iOS中,每个view背后都一个对象的layer对象(view背后的女人_),这样的view被称为layer-backed view。view为此layer的delegate,为它提供显示内容和对决定如何对属性变化进行动画的处理(- actionForLayer:forKey:)。例如我们修改view的root layer的属性,没有隐式动画产生,就是因为view作为它的delegate关闭了此场景下的『隐式动画』(但放在动画block中又会自动开启)。

当然layer不是一定要关联view才能存在,你可以创建一个没有view与之对应的layer。然后把它添加到你喜欢的layer中作为子layer。

动画接口API

iOS为我们提供了两套动画的API,一种是Core Animation的,另一种是UIView的动画block。这两者又有何异同呢?
实质上是一样的,UIView的block的动画就是对Core Animation的封装,方便我们使用。当然直接使用更底层的接口,能做出更加丰富的动画效果。

没图说个什么鬼

最后上一张CALayer的梳理图:

CALayer.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,004评论 5 13
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,322评论 6 30
  • 转载:http://www.jianshu.com/p/32fcadd12108 每个UIView有一个伙伴称为l...
    F麦子阅读 5,960评论 0 13
  • 每个UIView有一个伙伴称为layer,一个CALayer。UIView实际上并没有把自己画到屏幕上;它绘制本身...
    shenzhenboy阅读 3,027评论 0 17
  • 推荐指数,两颗星题目来源于英国作家克莱儿·麦克福尔的畅销小说《摆渡人》。说来也巧我一向不喜欢看畅销小说,所以《摆渡...
    不知莫向阅读 352评论 0 3