Co reAnimation是一个复合引擎,它的职责就是组合屏幕上不同的可视内容,这个内容是被分解成独立的图层,存储在一个叫做图层树的体系之中。于是这个树形成了UIKit以及在iOS应用程序当中你所能在屏幕上看到的一切的基础。
UIView
一个视图就是在屏幕上显示的一个矩形块(图片、文字、视频),它能够拦截类似于鼠标点击或者触摸手势等用户输入。视图在层级关系中可以互相嵌套,一个视图可以管理它的所有子视图的位置。
所有的视图都从一个叫UIView的基类派生而来,UIView可以处理触摸事件,可以支持基于CoreGraphics绘图,可以做仿射变换,或者类似于滑动或者渐变的动画。
CALayer
CALayer类在概念上和UIView类似,同样也是一些被层级关系管理的局限块,同样也可以包含一些内容(像图片,文本或者背景色),管理子图层的位置。它们有一些方法和属性做动画和变换。和UIView最大的不同是CALayer不处理用户的交互。CALayer并不清楚具体的响应链(iOS通过视图层级关系用来传送触摸事件的机制),于是它并不能响应事件。
平行的层级关系
每一个UIView都有一个CALayer实例的图层属性,视图的职责就是创建并管理这个图层,以确保当子视图在层级关系中添加或者被移除的时候,他们关联的图层也同样对应在层级关系树中有相同的操作。
实际上背后关联的图层才是真正用来在屏幕上显示和做动画,UIView仅仅是对它的一个封装。
为什么iOS要基于UIView和CALayer提供两个平行的层级关系呢?原因在于职责分离,这样也能避免很多重复代码。
contents属性
CALayer有一个属性叫做contents,这个属性的类型是id。在实践中,你如果在iOS系统上给contents赋的不是CGImage,得到的图层将是空白的。真正赋值的类型应该是CGImageRef,它是一个指向CGImage结构的指针。
这是因为在MACOS系统上,这个属性对CGImage和NSImage类型的值都起作用。
contentsScale属性
contentsScale 属性定义了寄宿图的像素尺寸和视图大小的比例,默认情况下它是一个值为1.0的浮点数。
contentsScale并不是总会对屏幕上的寄宿图有影响。因为由于设置了contentsGravity属性,它已经被拉伸适应图层的边界。所以contentsScale不起作用。
contentsScale属性属于支持高分辨率(又称Hi-DPI或Retina)屏幕机制的一部分。它用来判断在绘制图层的时候应该为寄宿图创建的空间大小,和需要显示的图片的拉伸度。如果contentsScale设置为1.0,将会以每个点1个像素绘制图片,如果设置为2.0,将会以每个点2个像素绘制图片,这就是Retina屏幕。
contentsRect属性
CALayer的contentsRect属性允许在图层边框里显示寄宿图的一个子域。涉及到图片是如何显示和拉伸的,所以要比contentsGravity灵活多了。和bounds、frame不同,contentsRect不是按点来计算的,它使用了单位坐标,单位坐标指定在0到1之间,是一个相对值(像素和点是绝对值)。所以它是相对于寄宿图的尺寸的。
iOS的坐标系统
点-点就像是虚拟的像素,也被称作逻辑像素。在标准设备上一个点就是一个像素,但是在retina屏幕上,一个点等于2*2个像素。iOS用点作为屏幕的坐标测算体系就是为了在Retina设备和普通设备上能有一致的视觉效果。
像素-物理像素坐标并不会用来屏幕布局,但仍然与图片有相对关系。
单位-对于与图片大小或是图层边界相关的显示,单位坐标是以恶搞方便的度量方式,当大小改变的时候,也不需要再次调整。单位坐标在OpenGl这种纹理坐标系统中用得多,coreainmation也用到了。
contentsCenter属性
contentsCenter其实是一个CGRect,它定义了一个固定的边框和一个在图层上可拉伸的区域。改变contentsCenter的值不会影响到寄宿图的显示,除非这个图层的大小改变了。
网友评论