《ios核心动画高级技巧》阅读笔记(1)

第一章 图层树

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
2
3
4
5
6
7
8
9
- (void)viewDidLoad {
[super viewDidLoad];

CALayer *blueLayer = [[CALayer alloc] init];
blueLayer.frame = CGRectMake(50, 50, 50, 50);
blueLayer.backgroundColor = [UIColor blueColor].CGColor;
[self.layerView.layer addSublayer:blueLayer];

}
  • 使用图层而不使用视图的情况
    • 开发可以在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},则显示效果如下图:

contentsRect

  • contentRect的另外一个用途就是ImageSprites(图片拼合),把多张图片放在一张大的图片上,然后使用contentRect分别显示每一张图片,去掉不显示的部分,这就是图片拼合。在游戏编程中非常常见。加载一张大图要比加载多张小图效率要高。

contentsCenter属性

  • contentsCenter属性表示图层相对于寄宿图的位置与大小,可以用来定义图片的拉伸。
  • 如下图,虚线框为图层的区域,灰色为内容的区域。

contentCenter

  • 该属性相当于UIImage的resizableImageWithCapInsets:方法

customDrawing

  • 除了直接给contents属性设置CGImage,也可以通过CoreGraphics直接绘制寄宿图。使用UIVIew 的drawRect:方法来自定义绘制
  • 除了重写drawRect:方法,也可以通过设置CALayer的代理,使用代理方法(void)displayLayer:来实现重绘,但是强烈建议使用前一种方法。