16/04/20 第一章
1.
CALayer
与UIView
的最大区别就是CALayer
不能处理用户交互, 虽然CALayer
提供了一些方法来判断触摸点是否在图层的范围内,但是CALayer
并不清楚具体的响应链.UIView
仅仅是对CALayer
的封装并提供了一些处理触摸的具体功能以及Core Animation
底层方法的高级接口, 所以在性能上CALayer
优于UIView
.2. 每个UIView都有一个CALayer的实例属性(backing layer), 视图的职责就是创建并管理这个图层以确保当子视图在层级关系中添加或被移除时候,他们关联的图层所对应的层级关系树中也同样有相同的操作.
16/04/20 第二章 CALayer一些属性
Contents
CALayer
的contents属性
之所以为id
是Mac OS的历史原因造成的,在Mac OS上contents属性
对CGImage
和NSImage
都做支持,所以用了id
.CALayer
的contents属性
只能用CGImageRef
来赋值.CGImageRef
是一个指向CGImage结构体
的指针. 可以通过UIImage
的CGImage属性
来获得CGImageRef
(image.CGImage).但是CGImageRef
是Core Fundation
类型,并不是Cocoa
的对象, 所以需要桥接一下(__bridge id _Nullable)(image.CGImage);
ContentsGravity
- 当给
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
CALayer
中的contentsScale属性
的定义:像素尺寸和视图大小的比例,默认值为1.0;如果设置为1.0则表示将会以每个点一个像素绘制图片,如果设置为2.0,那么以每个点两个像素绘制图片.当设置了contentsGravity时,会优先采纳contensGravity.
maskToBounds
CALayer
与UIView
一致,默认情况下会显示超出边界的内容.即maskToBounds属性默认为NO, 设置成YES可不显示超出部分,UIView
对应的是clipsToBounds;
contentsRect
- 默认的contentsRect是 {0, 0, 1, 1}. 如果指定一个小一些的矩形范围,图片将会被裁剪.
Custom drawing
- 给layer设置图形还可以通过drawRect方法自定义绘制,
drawRect
方法没有默认实现, 苹果建议;如果没有自定义绘制任务的需求,不要在创建一个空的drawRect
方法,会造成CPU资源和内存资源的浪费. CALayer
有一个delegate
属性,实现了CALayerDelegate
协议.协议中所有方法都是可选的. 当需要重绘时,CALayer
会请求它的代理给他一个图片来显示,会调用- (void)displayLayer:(CALayer *)layer;
如果代理没有实现- (void)displayLayer:
这个方法, 就会调用- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
; 在调用此方法前,CALayer创建了一个合适尺寸的空的寄宿图(尺寸由bounds和contentsScale决定)和一个Core Graphics的图形上下文,为绘制寄宿图做准备.- 使用CALayerDelegate绘制图形时,不对超出边界外的内容提供绘制支持.