第一章 图层树
CoreAnimation简介
- 动画只是CoreAnimation特性的冰山一角
- CoreAnimation是一个复合引擎,它的职责就是尽可能快地组合屏幕上不同的可视内容,这个内容被分解成独立的图层,存储在一个叫图层树的体系中。
图层与视图
- CALayer类在概念上和UIView类似,同样是一些被层级关系树管理的矩形块,同样可以含有一些内容。他有一些方法和属性用来做动画和变换。
- 和UIView最大的不同是,CALayer不处理用户的交互。CALayer并不清楚具体的响应链,因此它并不能响应时间。
- 每个UIView都有一个CALayer属性,即所谓的bakinglayer,视图的职责就是创建并管理这个图层。视图的层级关系与其图层的层级关系是相同的。
- 真正在界面上显示和进行动画的都是CALayer,UIView只是对CALayer的一个封装而已。
- 进行视图和图层的分类,是为了职责分离,避免重复的代码。ios中视图为UIView,MacOS中视图为NSView,但是他们的图层都是CALayer。
图层的能力
- CALayer能做但UIView不能做的东西:
- 阴影,圆角,带颜色的边框
- 3D变换
- 非矩形范围
- 透明遮罩
- 多级非线性动画
使用图层
- 可以直接在UIView的layer属性中添加图层,如下
1 | - (void)viewDidLoad { |
- 使用图层而不使用视图的情况
- 开发可以在MacOS上运行的跨平台应用
- 使用多种CALayer的子类(特殊图层),并且不想创建单独的UIView去封装他们
- 做一些对性能特别挑剔的工作
第二章 寄宿图
CALayer除了可以设置颜色,也可以设置一张图片,这张图片称为CALayer的寄宿图。
contents属性
- CALayer有一个contents的属性,它虽然是id类型,但是必须设置一个CGImage,才能显示出图片,设置为其他类型,都只会显示一个空白的区域。这种现象是有Mac OS的历史历史原因造成的。在Mac OS上,contents对CGImage和NSImage类型的值都起作用,但在ios中,不能给contents设置一个UIImage。
- contentGravity属性:与UIView中的contentMode属性对应
- contentScale属性:定义了寄宿图的像素尺寸和视图的比例,默认为1.0。UIView中与之对应的属性为contentScaleFactor。使用UIImage加载图片会自动根据屏幕加载2x或3x图片,但是使用CGImage则不会。这样我们就需要手动设置contentScale属性来修复这个问题。一般使用代码设置寄宿图,都会手动设置contentScale,如下:
blueLayer.contentsScale = [[UIScreen mainScreen] scale];
- maskToBounds属性用来决定是否显示超出边界的内容
contentsRect属性
- contentRect属性允许我们在图层边框里显示寄宿图的一个子域,这要比contentGravity属性灵活许多。contentRect是一个单位坐标,长宽最大都为1。默认为{0,0,1,1},当设置为{0,0,0.5,0.5},则显示效果如下图:
- contentRect的另外一个用途就是ImageSprites(图片拼合),把多张图片放在一张大的图片上,然后使用contentRect分别显示每一张图片,去掉不显示的部分,这就是图片拼合。在游戏编程中非常常见。加载一张大图要比加载多张小图效率要高。
contentsCenter属性
- contentsCenter属性表示图层相对于寄宿图的位置与大小,可以用来定义图片的拉伸。
- 如下图,虚线框为图层的区域,灰色为内容的区域。
- 该属性相当于UIImage的
resizableImageWithCapInsets:
方法
customDrawing
- 除了直接给contents属性设置CGImage,也可以通过CoreGraphics直接绘制寄宿图。使用UIVIew 的drawRect:方法来自定义绘制
- 除了重写drawRect:方法,也可以通过设置CALayer的代理,使用代理方法
(void)displayLayer:
来实现重绘,但是强烈建议使用前一种方法。