CALayer
CALayer用来在屏幕上显示和做动画,UIView仅仅是对CALayer的一个封装,可以通过UIView的高级API间接地使得动画变得很简单UIView没有暴露出来的CALayer的功能:- contents - 我们可以使用
CALayer来展示一张图片,而不用UIImageView
layer.contents = (__bridge id)image.CGImage;
contentGravity - 与
UIImageView的contentMode属性一样,contentsGravity的目的是为了决定内容在图层的边界中怎么对齐,contentsGravity可选的常量值有以下一些:- kCAGravityCenter
- kCAGravityTop
- kCAGravityBottom
- kCAGravityLeft
- kCAGravityRight
- kCAGravityTopLeft
- kCAGravityTopRight
- kCAGravityBottomLeft
- kCAGravityBottomRight
- kCAGravityResize
- kCAGravityResizeAspect
- kCAGravityResizeAspectFill
contentsScale - 设置图层的
contentsScale属性,适配Retina屏幕
layer.contentsScale = [UIScreen mainScreen].scale;maskToBounds-
UIView(clipsToBounds),CALayer(masksToBounds)决定是否显示超出边界的内容contentsRect - 定义了展示的区域,默认是{0, 0, 1, 1},改为{0,0,0.5,0.5},图片就会被裁剪

contentsCenter - 定义了一个固定的边框和一个在图层上可拉伸的区域,默认是{0, 0, 1, 1},
contentsCenter设置为{0.25, 0.25, 0.5, 0.5}的效果:
-drawRect: - 重载该方法,会为视图分配一个寄宿图,这个寄宿图的像素尺寸等于视图大小乘以
contentsScale的值。如果没有自定义绘制的任务就不要在子类中写一个空的-drawRect:方法。当调用了
setNeedsDisplay,会自动调用-drawRect:重绘,重绘时,CALayer会请求它的CALayerDelegate(非正式协议,其实就是说没有CALayerDelegate @protocol可以让你在类里面引用)给他一个寄宿图来显示。它通过调用下面这个方法做到的:-(void)displayLayer:(CALayerCALayer *)layer;趁着这个机会,如果代理想直接设置
contents属性的话,它就可以这么做,不然没有别的方法可以调用了。如果代理不实现-displayLayer:方法,CALayer就会转而尝试调用下面这个方法:-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;CALayer不会自动重绘它的内容,它把重绘的决定权交给了开发者,所以我们需要CALayer重绘时要显式地调用-display锚点(anchorPoint) - 默认位于图层的中点,所有图层的将会以这个点为中心放置,
anchorPoint可以被移动,比如你可以把它置于图层frame的左上角,于是图层的内容将会向右下角的position方向移动,而不是居中了
改变了
anchorPoint,position属性保持固定的值并没有发生改变,但是frame却移动了。
视觉效果
阴影
shadowOpacity:设置大于默认值(也就是0)的值,阴影就可以显示,//0.0(不可见) 1.0(完全不透明)
shadowColor:控制着阴影的颜色,默认是黑色
- shadowOffset:控制着阴影的方向和距离,默认值是 {0, -3},宽度控制这阴影横向的位移,高度控制着纵向的位移
shadowRadius:控制着阴影的模糊度,当它的值是0的时候,阴影就和视图一样有一个非常确定的边界线。当值越来越大的时候,边界线看上去就会越来越模糊和自然
给
shadowRadius设置一个稍大的值
图层蒙板 -
mask,mask本身就是个CALayer类型,有和其他图层一样的绘制和布局属性,mask图层定义了父图层的部分可见区域
拉伸过滤 -
CALayer有三种拉伸过滤方法,他们是:- kCAFilterLinear
- kCAFilterNearest
kCAFilterTrilinear
- 较小的图或者是差异特别明显、极少斜线的大图,Nearest会保留这种差异明显的特质以呈现更好的结果
对于大多数的图尤其是有很多斜线或曲线轮廓的图片,选用kCAFilterLinear或kCAFilterTrilinear
如下,默认的
kCAFilterLinear选项让我们失望了
改变过滤的方法
`view.layer.magnificationFilter = kCAFilterNearest;`

组透明
alpha(UIView)、opacity(CALayer)都会影响子层级的
组透明整体实现方案
- UIViewGroupOpacity -> YES(Info.plist)
- allowsGroupOpacity(IOS7+可用,相当于UIViewGroupOpacity)
- shouldRasterize+rasterizationScale(配置屏幕),如果它被设置为YES,在应用透明度之前,图层及其子图层都会被整合成一个整体的图片
变换
仿射变换
- 混合变换,变换的顺序会影响最终的结果,也就是说旋转之后的平移和平移之后的旋转结果可能不同
3D变换
- 透视投影(m34),
m34的默认值是0,我们可以通过设置m34为-1.0 / d来应用透视效果,d代表了想象中视角相机和屏幕之间的距离,通常设置为500~1000
- 透视投影(m34),
灭点 - 永远位于图层变换之前
anchorPoint的位置sublayerTransform - 一次性对包含这些图层的容器做变换
doubleSided - 不渲染背面,不影响事件响应,设置hidden或alpha为0会影响事件响应
专用图层
CAShapeLayer - 通过矢量图形而不是bitmap来绘制的图层子类
优点:
- 渲染快速(硬件加速)
- 高效使用内存(不需创建寄宿图)
- 不会被图层边界剪裁掉(可以在边界之外绘制)
- 不会出现像素化(矢量图形)
- 圆角 - 可以单独指定每个角
CATextLayer - 使用了Core text,并且渲染得非常快
- 防止像素化
textLayer.contentsScale = [UIScreen mainScreen].scale;
- 防止像素化
CATransformLayer - 不能显示它自己的内容。只有当存在了一个能作用域子图层的变换它才真正存在
CAGradientLayer - 生成两种或更多颜色平滑渐变,真正好处在于绘制使用了硬件加速
- 基础渐变
startPoint和endPoint属性,他们决定了渐变的方向colors属性,决定了渐变的颜色- 多重渐变
locations属性定义了colors属性中每个不同颜色的位置,非强制要求设置,但是如果你给它赋值了就一定要确保locations的数组大小和colors数组大小一定要相同
- 基础渐变
CAReplicatorLayer - 高效生成许多相似的图层
- 重复图层(Repeating Layers)
- `instanceCount`属性指定了图层需要重复多少次 - `instanceTransform`指定了一个`CATransform3D`3D变换 - 反射 - [ReflectionView](https://github.com/nicklockwood/ReflectionView)
- 重复图层(Repeating Layers)
-
scrollToPoint:方法,它自动适应bounds的原点以便图层内容出现在滑动的地方- 内容完全可以超过边界
UIScrollView并没有用CAScrollLayer
CATiledLayer - 将大图分解成小片然后将他们单独按需载入
- 小片裁剪,大图裁剪成小图,用
CATiledLayer展示
- 小片裁剪,大图裁剪成小图,用
CAEmitterLayer - 高性能的粒子引擎,被用来创建实时例子动画如:烟雾,火,雨等等这些效果
preservesDepth - 是否将3D例子系统平面化到一个图层(默认值)或者可以在3D空间中混合其他的图层
renderMode - 控制着在视觉上粒子图片是如何混合的,
kCAEmitterLayerAdditive是叠加效果,其他是覆盖效果CAEmitterCell -
CAEmitterLayer看上去像是许多CAEmitterCell的容器,这些CAEmitierCell定义了一个粒子效果。你将会为不同的粒子效果定义一个或多个CAEmitterCell作为模版,同时CAEmitterLayer负责基于这些模版实例化一个粒子流。一个CAEmitterCell类似于一个CALayer:它有一个contents属性可以定义为一个CGImage,另外还有一些可设置属性控制着表现和行为。- 这种粒子的某一属性的初始值。比如,
color属性指定了一个可以混合图片内容颜色的混合色。在示例中,我们将它设置为桔色。- 例子某一属性的变化范围。比如
emissionRange属性的值是2π,这意味着例子可以从360度任意位置反射出来。如果指定一个小一些的值,就可以创造出一个圆锥形 - 指定值在时间线上的变化。比如,在示例中,我们将
alphaSpeed设置为-0.4,就是说例子的透明度每过一秒就是减少0.4,这样就有发射出去之后逐渐小时的效果。
- 例子某一属性的变化范围。比如
- 这种粒子的某一属性的初始值。比如,
CAEAGLLayer - 最后的杀手锏,OpenGL
- 所有东西都是3D空间中有颜色和纹理的三角形
- GLKit框架
-
AVFoundation框架提供- 支持3D,圆角,有色边框,蒙板,阴影等效果