UIView 与 CALayer
1,CALayer不处理用户交互。CALayer不知道具体的事件响应链。但是提供方法判断一个触点是否在图层的范围之内。
2,每一个UIView都有一个CALayer实例的图层属性。视图的职责是创建并管理这个图层。
3,UIView是对它的封装,提供iOS处理触摸的具体功能,以及Core Animation底层方法的高级接口。
4, CALayer 是UIView内部实现细节。
为什么提供平行的关系?
职责分离。避免重复代码。iOS UIKit和UIView MacOS 有AppKit 和NSView iOS与MacOS 共享代码。
UIView未暴露的CALayer的功能:
阴影 圆角 带颜色的边框
3D变换
非矩形范围
透明遮罩
多级非线性动画
优化tip
SDWebImage 在这个 Demo 里仍然会产生少量性能问题,并且有些地方不能满足我的需求,所以我自己实现了一个性能更高的图片加载库。在显示简单的单张图片时,利用 UIView.layer.contents 就足够了,没必要使用 UIImageView 带来额外的资源消耗,为此我在 CALayer 上添加了 setImageWithURL 等方法。除此之外,我还把图片解码等操作通过 YYDispatchQueuePool 进行管理,控制了 App 总线程数量。
contentsCenter
随意设置尺寸 边框仍然是连续的。UIImage resizableImageWithCapInsets。类似。
Custom Drawing
CALayer的contents赋CGImage的值 设置寄宿图的方法。可以通过继承UIView 实现drawRect 自定义绘制。
寄宿图的大小为 像素尺寸 * contentsScale
布局
UIView :frame bounds center。
CALayer : frame bounds position
存取方法。实际上是取得位于视图下方CALayer的属性。
frame 是基于bounds position transform 计算而来。
hit Testing
CALayer 不关心相应链 不能处理 触摸事件和手势 会有方法处理事件
containsPoint
hitTest 判断当前点击的layer
自动布局
UIViewAutoresizingMask 父试图改变 相应的UIView的frame 也会更新。控制CALayer的·布局用 CALayerDelegate
- (void)layoutSublayersOfLayer:(CALayer *)layer;
圆角阴影
maskToBounds 剪裁阴影
我们只把阴影用在最外层的视图上,内层视图进行裁剪
shoadowPath根据内容形状继承 若提前知道形状 可以
CGMutablePathRef circlePath = CGPathCreateMutable();
CGPathAddEllipseInRect(circlePath, NULL, self.layerView2.bounds);
self.layerView2.layer.shadowPath = circlePath; CGPathRelease(circlePath);
提前指定。
图层蒙版
//create mask layer
CALayer *maskLayer = [CALayer layer];
maskLayer.frame = self.layerView.bounds;
UIImage *maskImage = [UIImage imageNamed:@"Cone.png"];
maskLayer.contents = (__bridge id)maskImage.CGImage;
//apply mask to image layer
self.imageView.layer.mask = maskLayer;
蒙版可以通过代码甚至代码实时生成。
拉伸过滤
kCAFilterLinear//拉伸放大 双线性滤波算法
kCAFilterNearest//最近过滤
kCAFilterTrilinear
组透明
alpha 和 opacity 都影响子层级
shouldRasterize YES 图层及子图层都会整合成一个整体的图片。没有透明度问题。