1.图树层
图层的树状结构
Core Animation其实是一个令人误解的命名。你可能认为它只是用来做动画的,但实际上它是从一个叫做CAlayer Kit这么一个不怎么和动画有关的名字演变而来,所以做动画这只是Core Animation特性的冰山一角。
Core Animation是一个复合引擎,他的职责就是尽可能地组合屏幕上不同的可是内容,这个内容是被分解成独立的图层,储存在一个叫做图层树的体系之中。于是这个树形成了UIKit以及在ios 应用程序当中你所能在屏幕上看见的一切的基础。
在讨论动画之前,我们将从图层开始,设计一下Core Animation的静态组合以及布局特性。
1.1图层与视图
如果你曾经在iOS上或者是Mac OS平台上写过应用程序,你可能会对视图的概念比较熟悉。一个视图就是在屏幕上显示的一个矩形块(比如图片,文字或者视频),他能够拦截类似于鼠标点击或者触摸手势等用户输入。视图在层级关系中可以相互嵌套,一个视图可以管理他的所有子视图的位置。图1.1显示了一种典型的视图层级关系。
图1.1一种典型的iOS屏幕(左边)和矩形视图的层级关系(右边)CALayer
CALayer类在概念上和UIView类似,同样也是一些被层级关系树管理的矩形块,同样也可以包含一些内容(如图片,文字或者背景颜色),管理子图层的位置。他们有一些方法和属性用来做动画和变换。和UIView最大的不同四CALayer不处理用户的交互。
CALayer并不清楚具体的响应者链(iOS通过视图层级关系用来传送触摸事件的机制)于是它并不能够响应事件,即使它提供了一些方法来判断是否一个触点在图层的范围之内(具体见第三章,“图层的几何学”)
平行的层级关系
每一个UIView都有一个CALayer实例的图层属性,也就是所谓的backing layer,视图的职责就是创建并管理这个图层,以确保当子视图在层级关系中添加或者被移除的时候,他们关联的图层也同样应在层级关系树种有相同的操作。(见图1.2)。
图1.2-层的树状结构(左边)以及对应的视图层级(右边)
实际上这些背后关联的图层才是真正用来在屏幕上显示和做动画,UIView仅仅是对它的一个封装,提供了一些iOS类似于处理触摸的具体功能,以及Core Animation底层方法的高级接口。
但是为什么iOS要基于UIView和CALayer提供两个平行的层级关系呢?为什么不用一个简单的层级来处理所有的事情呢?原因在与要做职责分离,这样也能避免很多重复代码,在iOS和Mac OS两个平台上,时间和用户交互很多地方的不同,基于多点触控的用户界面和基于鼠标键盘有着本质的区别,这就是为什么iOS有UIKit和UIView,但是Mac OS有AppKit和NSView的原因。他们在功能上类似,但是在实现上有显著的区别。
绘图,布局和动画,相比之下就是类似Mac笔记本和桌面系列一样应用于iPhone和iPad触屏的概念。把这种功能的逻辑分开并应用到独立的Core Animation框架,苹果就能在iOS和Mac OS之间共享代码,使得对苹果自己的OS开发团队和第三方开发者去开发两个平台的应用更加便捷。实际上,这里并不是两个层级关系,而是四个,每一个都扮演着不同的角色,除了视图层级和图层树之外,还存在呈现树和渲染 树,将在第七章“隐式动画”和第十二章“性能调优”分别讨论。
1.2图层的能力
如果说CALayer是UIView内部实现细节,那我们为什么要全面地了解他呢?苹果当然为我们提供了优美简洁的UIView接口,那么我们是否就没必要直接去处理Core Animation的细节了呢?
某种意义上说的的确是这样,对一些简单的需求来说,我们确实没必要处理CALayer,因为苹果已经通过UIView的高级API间接地使动画变得很简单。
但是这种简单会不可避免地带来一些灵活上的缺陷。如果你略微想在底层做一些改变,或者使用一些苹果没有在UIView上实现的接口功能,这时除了介入Core Animation底层之外别无选择。
我们已经证实了图层不能像视图那样处理触摸事件,那么他能做哪些视图不能做的呢?这里有一些UIView没有暴露出来的CALayer的功能:
1.阴影,圆角,带颜色的边框
2.3D变换
3.非矩形范围
4.透明遮罩
5.多级非线性动画
1.3使用图层
创建一个新的工程,使用Single View Application模板创建一个工程
在屏幕中央创建一个小试图,(大约200x200的尺寸),叫做layerView,改变背景View的颜色。
运行项目,在屏幕中间应该能看见一个白色小块。
然后创建一个CALayer,把它作为我们试图相关图层的子图层。
尽管UIView类接口中暴漏了图层属性,但是标准的Xcode项目模板并没有包含Core Animation相关头文件,所以要引入QuartzCore框架到项目工程中,才能引用图层相关的方法或者访问它的属性。
在vc的点m引入库。
在代码中直接引用CALayer的属性和方法。设置它的backgroundCokor属性,然后添加到layerView背后相关图层的子图层。