IOS核心动画高级一:图层树

图层树

先来介绍几个我们常见的名词:
Core Animation:只看它的名字会让人产生一种误解——核心动画。从功能方面来看这并不能体现他的强大之处,Core Animation 是从一个Layer Kit 的库演变而来的(当然 Layer Kit 这个名字就不会让我们直接联想到动画相关了),动画对 Core Animation 来说只是其中的一部分。

Core Animation 是一个复合引擎,它的职责就是尽可能快的组合屏幕上不同的可视内容,这个内容是被分解成独立的图层,存储在一个叫做图层树的体系之中。**于是这个树形成了UIKit 和在ios应用程序中你所能在屏幕上看见的一切内容的基础。

在开始核心动画之前,我们先从图层树开始,了解一些 Core Animation 的静态组合和“布局特性”。

图层与视图

视图——UIView

如果你在ios应用程序的开发经验,对视图概念应该是比较熟悉,一个视图就是一个屏幕上显示的矩形块(比如图片,视频、文字),同时它能够拦截类似鼠标点击或者触摸手势等的用户输入。视图在层级关系中可以互相嵌套,一个视图可以管理它所有子视图的位置。

1.1——左边是ios屏幕显示效果,右边是形成视图的层级关系.jpeg

在 ios 中所有的视图都是从 UIView 基类中派生出来的,UIView 可以处理触摸事件,可以支持基于 Core Graphics 的绘制,可以做仿射变换(例如旋转或者缩放),或者简单的类似于滑动(frame)或者渐变(alpha)的动画

图层——CALayer

CALayer 和 UIView 在概念上类似,同样也是一些被层级关系树管理的矩形块,同样也包含一些内容(比如图片,文字,背景色),同样它也管理他所有的子图层的位置,它们也有一些方法和属性用来做动画和变换。 和 UIView 最大的不同是:CALayer 不处理用户的交互(类似鼠标点击,触摸手势)

CALayer 并不清楚具体的响应链(ios 通过视图层级关系用来传递触摸事件的机制),所以它并不能够响应事件,即使他提供了一些方法来判断是否一个触点在图层范围之内(后文有介绍)。

平行的层级关系

每一个 UIView 都有一个 CALayer 类型的图层属性。也就是所谓的 backing layer(永久层),视图的职责就是创建并管理这个图层,以确保子视图在层级关系中添加或者删除的时候,他们关联的图层也同样对应在层级关系树中有相同的操作

1.2——左边是图层的树状结构,右边是对应的视图层级

实际上这些背后关联的图层才是真正用来在屏幕上显示和做动画的, UIView 仅仅是对它的一个封装,提供了一些ios类似处理触摸事件的一些具体功能。以及一些使用 Core Animation 底层方法的高级接口。

此时大家可能就有疑问:IOS为什么要基于 UIView 和 CALayer 提供两套平行的层级关系呢?为什么不使用一个简单的层级来处理所有的事情?好问题,原因在于 要做职责分离,这样也能避免很多重复代码。在 ios 和 macOS 两个平台上,事件和用户交互有很多地方的不同,基于多点触控的用户界面和基于鼠标和键盘有着本质的区别,这就是为什么ios有 UIKit 和 UIView , MacOS 有AppKit 和 NSView 。他们在功能很相似,但是在实现上有着显著的区别。

绘图、布局和动画相比之下就是类似Mac 笔记本和桌面系列一样应用于iPhone和iPad触屏的概念。把两个平台上的这种功能的逻辑分开应用到独立的 Core Animation 框架,使得苹果的OS团队和第三方开发者去开发两个平台的应用更加便捷。

实际上,这里并不是两个层级关系,而是四个,每一个都扮演不同的角色,除了视图层级和图层树之外,还存在呈现树渲染树,我们在后面的介绍。

图层CALayer的能力

如果说 CALayer 是 UIView 的内部实现细节,那 我们为什么还要费劲心思的了解他呢?当然苹果位我们提供了优美简洁的 UIView 的接口,那么我们是否就没有必要直接去处理 Core Animation 一些实现上的细节了呢?

在某种程度是确实是这样,对一些简单的需求来说,我们确实没有必要处理 CALayer , 苹果已经通过UIView 的高级API间接地使得动画变得很简单。

但是这种简单不可避免的会带来灵活上的一些缺陷、如果你略微想在底层做一些改变,或是想要使用一些苹果没有在 UIView 中实现的接口功能,这时候处了介入Core Animation底层之外 别无其他选择。

我们已经证实了图层不能像视图那样处理触摸时间,那它能做那些视图不能做的呢?举例一些 UIView 没有暴露出的 CALayer 功能。

  • 圆角,阴影,带颜色的边框
  • 3D的动画变换
  • 非举行范围绘制。
  • 透明遮罩
  • 多级非线性动画

跟着我们学习的脚步,我们会一一为大家讲解这些功能,但在此之前,我们首先要关注最基本的,CALayer 是如何被使用的。

使用图层

我们使用代码的形式进行演示,
创建项目的代码我们就省去了,节约大家时间
项目创建完成

项目创建完成.png

首先我们在创建一个子视图(layerView)添加到 viewController 的视图上。
效果如下:

子视图效果.png

然而这并没有什么卵用,
我们想要在白色的视图中添加一个蓝色的区域,当然你可以通过添加子视图的方式实现,但这对我们的学习layer没有什么卵用。

因此我们通过创建图层来完成。于是呢我们创建一个layer图层,并且把它作为我们视图相关图层的子图层。尽管 UIView 的接口中暴露了图层属性,但是标准的Xcode项目并包含Core Animation 的相关头文件,所以如果我们不给项目添加合适的库,是不能使用任何图层相关的方法或者访问他的属性的。所以首先需要添加QuartzCore 框架到building phases下。
如图所示:

添加库.png

之后就可以在代码中应用CALayer的属性和方法了,我们创建一个Layer 设置蓝色添加到layerView相关图层的子图层上,
代码如下

UIView *layerView = [[UIView alloc] initWithFrame: CGRectMake(100, 100, 200, 200)];
layerView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:layerView];

//添加一个图层
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(50, 50, 100, 100);
layer.backgroundColor = [UIColor blueColor].CGColor;
[layerView.layer addSublayer:layer];

咱们看效果:

看效果.png

一个视图只有一个相关联的图层(自动创建),同时它也可以支持添加无数多个子图层。从上面的例子我们可以看出,你可以显示创建一个单独的图层。并且把它直接添加到视图关联图层的子图层。尽管可以这样添加图层,但往往我们只是简单地处理视图,他们关联的图层并不需要额外地手动添加子视图。

额外补充:
在 MacOS平台,10.8版本之前,一个显著的性能缺陷就是 macOS 使用 UIView视图层级而不在一个单独的视图内使用CALayer树状层级。但在IOS平台,使用轻量级的 UIView类并没有显著的性能影响(当然在 MacOS 10.8系统之后,NSView 的性能有了很大的提升)

使用图层关联视图层级而不是用CALayer的好处在于,你能在使用所有CALayer 底层特性的同时,也可以使用UIView提供的高级API (比如,自动排版、布局,响应事件)

然而在以下场景,你可能更需要使用CALayer ,而不用使用UIView

  • 开发同时可以在Mac OS上运行的跨平台应用。
  • 使用多种 CALayer 的子类,并且不想创建额外的 UIView 去封装他们。
  • 做一些对性能特别挑剔的工作,(比如对 UIView 一些可忽略不计的操作都会引起性能方面显著的不同,当然,你也可以直接使用 openGL绘图)。
    当然这些场景比较少见,总体来说处理视图还是比直接处理图层方便一些。

文章总结:

我们文中阐述了图层的树状结构。说明了如何在ios中由 UIView 的层级关系形成的一种平行的CALayer层级关系,后面使用Demo进行了演示。

未完待续……

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

推荐阅读更多精彩内容