iOS Core Animation Advanced Techniques-图层的寄宿图
上一篇iOS Core Animation Advanced Techniques-图层树随笔中已经介绍了CALayer与UIView的一些关系,这篇主要是对CALayer中的寄宿图做一些总结。
CALayer的属性:
- contents(寄宿图):
虽然contents属性是id类型,但是只有附上CGImage对象也就是CGImageRef类型的时候才不会显示空白一片
-
-
- CGImageRef:一个指向CGimage结构的指针
- UIImage有一个CGImage属性,正是一个CGImageRef指针,但仍需要通过bridged关键字转换,如:
- layer.contents=(__bridge id)image.CGImage;//ARC下,非ARC不需要__bridge
-
-
-
- 使用例子:
- UIImage *image=[UIImage imageName:@"Photo.png"];
- self.myView.layer.contents=(__bridge id)image.CGImage;
-
- contentGravity:
决定内容在图层的边界中怎么对齐(在视图UIView上对应属性为contentMode)
可选常量值有:
-
-
- kCAGravityCenter
- kCAGravityTop
- kCAGravityBottom
- kCAGravityLeft
- kCAGravityRight
- kCAGravityTopLeft
- kCAGravityTopRight
- kCAGravityBottomLeft
- kCAGravityBottomRight
- kCAGravityResize
- kCAGravityResizeAspect
- kCAGravityResizeAspectFill
-
- contentsScale:
定义寄宿图的像素尺寸与视图大小的比例,默认1.0(在视图UIView上对应的属性为contentScaleFactor)
-
-
- 该属性会受contentGravity属性影响;
- 该属性属于支持高分屏机制的一部分(而非用来做放大图层的寄宿图)
- 该属性设置为2.0,将会每个点2个像素绘制图片
- 使用例子(图层适配图片):
- UIImage *image=[UIImage imageNamed:@"Photo.png"];
- self.myView.layer.contents=(__bridge id)image.CGImage;
- slef.myView.layer.contentsGravity=kCAGravityCenter;//不会拉伸图片而影响contentsScale的属性设置
- self.myView.layer.contentsScale=image.scale;
- /*图层适配屏幕时:self.myView.layer.contentsScale=[UIScreen mainScreen].scale;*/
-
- maskToBounds:
-
- 决定是否显示超出边界的内容(在视图UIView上对应的属性为clipsToBounds)默认值为NO;
- UIView仍然会绘制超过边界的内容或是子视图,CALayer亦是如此;
-
- contentsRect:
-
- 在图层里决定显示寄宿图上的某一块rect子域
- 该属性是一个单位坐标:指定在0-1之间,是一个相对值
- 默认值{0,0,1,1}
- 使用例子:图片合并为一张大图一次性载入,然后赋给CALayer的contents再选取寄宿图的某块子域显示
- UIImage *image=[UIImage imageNamed:@"Photo.png"];
- self.myView.layer.contents=(__bridge id)image.CGImage;
- self.myView.layer.contentsGravity=kCAGravityResizeAspect;
- self.myView.layer.contentsRect=CGRectMake(0,0,0.5,0.5);
- iOS使用以下坐标系统:
- 点:
- 虚拟像素,标准设备上1点1像素,在高分屏上一点等于2*2甚至更多像素
- 像素:
- 单位:
-
- contentsCenter:
-
- 注意:该属性与寄宿图的位置没有关系
- 是一个CGRect,定义一个固定的边框和一个在图层上可拉伸的区域;
- 该属性只有在图层的大小改变了才看到效果
- 默认值{0,0,1,1},意味着如果大小改变了,那么寄宿图会均匀拉伸开。
-
- Custome Drawing:
-
- 另一种方式设置CALayer的contents寄宿图内容:用Core Graphics直接绘制寄宿图:
- 通过继承UIView实现-drawRect:方法自定义绘制
- -drawRect:方法没有默认实现,UIView检测到-drawRect:方法被实现,会给该UIView关联的CALayer设置contents分配一个寄宿图(像素尺寸等于视图大小乘以contentsScale)
- -drawRect:方法在UIView出现在屏幕上自动调用,方法体利用Core Graphics绘制寄宿图,然后内容被缓存起来直至需要被更新(显示调用了UIView的-setNeedsDisplay方法)
-
- delegate:
-
- 遵循CALayerDelegate这个非正式协议
- CALayer被重绘时回调代理方法-(void)displayLayer:(CALayer *)layer;以获取一个寄宿图
- 如果代理没有实现-(void)displayLayer:(CALayer *)layer;CALayer会先创建一个适合尺寸(由bounds和contentsScale决定)的空寄宿图,和一个Core Graphics的绘制上下文环境后回调-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;
- 使用例子:
- CALayer *myLayer=[CALayer layer];
- myLayer.frame=CGRectMake(50.0f,50.0f,100.0f,100.0f);
- myLayer.backgroundColor=[UIColor blueColor].CGColor;
- myLayer.delegate=self;
- myLayer.contentsScale=[UIScreen mainScreen].scale;
- [self.layerView.layer addSublayer:myLayer];
- [blueLayer display];//与UIView不同,CALayer图层显示在屏幕上时,不会自动重绘,要显示调用方法
- -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
- CGContextSetLineWidth(ctx,10.0f);
- CGContextSetStrokColorWithColor(ctx,[UIColor redColor].CGColor);
- CGContextStrokeEllipseInRect(ctx,layer.bounds);
- }
-