Core Animation 阅读随笔 第一二章

16/04/20 第一章


1. CALayerUIView的最大区别就是CALayer不能处理用户交互, 虽然CALayer提供了一些方法来判断触摸点是否在图层的范围内,但是CALayer并不清楚具体的响应链.UIView仅仅是对CALayer的封装并提供了一些处理触摸的具体功能以及Core Animation底层方法的高级接口, 所以在性能上CALayer优于UIView.
2. 每个UIView都有一个CALayer的实例属性(backing layer), 视图的职责就是创建并管理这个图层以确保当子视图在层级关系中添加或被移除时候,他们关联的图层所对应的层级关系树中也同样有相同的操作.

16/04/20 第二章 CALayer一些属性

Contents

  1. CALayercontents属性之所以为id是Mac OS的历史原因造成的,在Mac OS上contents属性CGImageNSImage都做支持,所以用了id.
  2. CALayercontents属性只能用CGImageRef来赋值. CGImageRef是一个指向CGImage结构体的指针. 可以通过UIImageCGImage属性来获得CGImageRef(image.CGImage).但是CGImageRefCore Fundation类型,并不是Cocoa的对象, 所以需要桥接一下(__bridge id _Nullable)(image.CGImage);

ContentsGravity

  1. 当给contents属性赋图时可能遇到与UIImageView相同的情况:拉伸方式不预期.而UIImageView的解决方法是更改contentMode属性,如:imageView.contentMode = UIViewContentModeScaleAspectFit;``UIView的分类中UIView(UIViewRendering)也有contentMode属性. 重点来了,事实上UIView对大多数视觉属性的操作,是对CALayer的操作.如contentMode,frame等. 而CALayer中与contentMode对应的属性是contentsGravity.相关常量值在头文件781-806行.self.view.layer.contentsGravity = kCAGravityResizeAspect;等效于imageView.contentMode = UIViewContentModeScaleAspectFit;

contentsScale

  1. CALayer中的contentsScale属性的定义:像素尺寸和视图大小的比例,默认值为1.0;如果设置为1.0则表示将会以每个点一个像素绘制图片,如果设置为2.0,那么以每个点两个像素绘制图片.当设置了contentsGravity时,会优先采纳contensGravity.

maskToBounds

  1. CALayerUIView一致,默认情况下会显示超出边界的内容.即maskToBounds属性默认为NO, 设置成YES可不显示超出部分, UIView对应的是clipsToBounds;

contentsRect

  1. 默认的contentsRect是 {0, 0, 1, 1}. 如果指定一个小一些的矩形范围,图片将会被裁剪.

Custom drawing

  1. 给layer设置图形还可以通过drawRect方法自定义绘制,drawRect方法没有默认实现, 苹果建议;如果没有自定义绘制任务的需求,不要在创建一个空的drawRect方法,会造成CPU资源和内存资源的浪费.
  2. CALayer有一个delegate属性,实现了CALayerDelegate协议.协议中所有方法都是可选的. 当需要重绘时,CALayer会请求它的代理给他一个图片来显示,会调用- (void)displayLayer:(CALayer *)layer; 如果代理没有实现- (void)displayLayer:这个方法, 就会调用- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx; 在调用此方法前,CALayer创建了一个合适尺寸的空的寄宿图(尺寸由bounds和contentsScale决定)和一个Core Graphics的图形上下文,为绘制寄宿图做准备.
  3. 使用CALayerDelegate绘制图形时,不对超出边界外的内容提供绘制支持.