Core Animation有个令人误解的命名,动画只是Core Animation特性的冰山一角。Core Animation是一个符合引擎,它的职责是尽可能快的组合屏幕上不同的可视内容,这个内容被分解成独立的图层,储存在一个叫图层树的体系中。
CALayer类在概念上和UIView类似。都是一些被层级关系树管理的矩形块,同样可以包含一些内容(图片,文本或背景色),管理子图层的位置。和UIView最大的不同时CAlayer不处理用户交互(可以通过一些方法来判断触点是否在图层范围内)。
使用图层
//create sublayer
CALayer *blueLayer = [CALayer layer];
blueLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
blueLayer.backgroundColor = [UIColor blueColor].CGColor;
//add it to our view
[self.layerView.layer addSublayer:blueLayer];
寄宿图
contents属性
contents属性的类型是id,意味着在使用中可以接收任何类型的对象,但是实践中发现如果接收的对象不是CGImage,则你得到的图层可能只是一片空白。
正确的使用:
layer.contents = (__bridge id)image.CGImage;
contentGravity
如果你创建的layer和你使用的image的宽高比不一致,那么你会发现你得到的效果会有些变形,如果你使用的是UIImageView你肯定就会使用contentMode属性来调整图片的填充(UIViewContentModeScaleAspectFit),CALayer也提供了对应的属性contentGravity,他是一个NSString类型,可选值有以下类型:
- kCAGravityCenter
- kCAGravityTop
- kCAGravityBottom
- kCAGravityLeft
- kCAGravityRight
- kCAGravityTopLeft
- kCAGravityTopRight
- kCAGravityBottomLeft
- kCAGravityBottomRight
- kCAGravityResize
- kCAGravityResizeAspect
- kCAGravityResizeAspectFill
我们可以使用kCAGravityResizeAspect来调整显示效果,等同于UIViewContentModeScaleAspectFit
layer.contentsGravity = kCAGravityResizeAspect;
contentsScale
定义了寄宿图的像素尺寸和视图大小的比例,默认是值为1.0的浮点数,如果你设置了contentsGravity属性,你可能会发现这个值没有作用。
contentsScale属性其实属于支持高分辨率屏幕机制的一部分,它用来判断在绘制图层的时候应该为寄宿图创建的空间大小,和需要显示图片的拉伸度(在没有设置contentsGravity属性的情况下)
contentsScale设置为1.0,将以么个点1个像素绘制,2.0则以每个点2个像素绘制,一般为了图像在不同设备上显示正确,可以使用
layer.contentsScale = [UIScreen mainScreen].scale;
maskToBounds
类比UIView的clipsToBounds属性
contentsRect
contentsRect是CGRect类型,是一个相对值,假定一张图片的size是(100,100),设置contentsRect的值为(0.1,0.1,0.8,0.8),则实际寄宿图可见的部分就是(10,10,80,80)。
contentsRect在app中可以用来进行图片拼合,即我们一次性载入一张大图,而在显示的时候选择性的显示其中的部分。
如下图可以如果需要分别显示四张图片,则设置的contentsRect分别是
(0,0,.5,.5),(0.5,0,0.5,0.5),(0,0.5,0.5,0.5),(0.5,0.5,0.5,0.5)
contentsCenter
contentsCenter是CGRect类型,定义了一个固定的边框和一个在图层上可拉伸的区域,改变contentsCenter并不会影响到寄宿图的显示,除非这个图层的大小改变了,才能看到效果。
默认(0,0,1,1)意味着如果大小改变了,那么寄宿图将被均匀的拉伸,如果设置为(0.25,0.25,0.5,0.5)则是只有相对位置的中间区域会被拉伸
Custom Drawing
给contents赋CGImage的值不是唯一的设置寄宿图的方法。我们还可以通过drawRect方法来自定义绘制。如果你不需要寄宿图,就不要创建这个方法,这会造成CPU资源和内存的浪费
drawRect虽然是一个UIView方法,事实上底层是CALayer安排了重绘工作和保存了因此产生的图片
CALayer可以通过设置代理实现CALayerDelegate协议,通过(不能再将某个UIView设置为CALayer的delegate,因为UIView对象已经是它内部根层的delegate,再次设置为其他层的delegate就会出问题,使用时建议创建一个CALayer的代理类)
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx