在CALayer上绘图
要在CALayer上绘图,有两种方法:
1. 创建一个CALayer的子类,然后覆盖drawInContext:方法,可以 使用Quartz2D API在其中进行绘图
2. 设置CALayer的delegate,然后让delegate实现 drawLayer:inContext:方法进行绘图
• 注意:
– 不能再将UIView设置为这个CALayer的delegate,因为UIView对象
已经是内部层的delegate,再次设置会出问题
– 无论使用哪种方法,都必须向层发送setNeedsDisplay消息,以触 发相应绘图方法的调用.
CALayer、UIView以及上下文之间的关系
• 当UIView收到setNeedsDisplay消息时,CALayer会准备好一个 CGContextRef,然后向它的delegate即UIView,发送消息,并且传入 已经准备好的CGContextRef对象。UIView在drawLayer:inContext:方 法中会调用自己的drawRect:方法.
• 平时在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由 CALayer传入的CGContextRef对象,在drawRect:中完成的所有绘图 都会填入CALayer的CGContextRef中,然后被拷贝至屏幕.
• CALayer的CGContextRef用的是位图上下文(Bitmap Graphics Context)
下面是使用代理实现的绘图操作:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor grayColor];
//--------------为UIView设置圆角边框--------------
// 设置该视图控制器所显示的UIView上的CALayer的圆角半径
self.view.layer.cornerRadius = 8;
// 设置该视图控制器所显示的UIView上的CALayer的边框宽度
self.view.layer.borderWidth = 4;
// 设置该视图控制器所显示的UIView上的CALayer的边框颜色
self.view.layer.borderColor = [UIColor redColor].CGColor;
//--------------创建简单的CALayer--------------
// 创建一个CALayer对象
CALayer *subLayer = [CALayer layer];
// 设置subLayer的背景颜色
subLayer.backgroundColor = [UIColor magentaColor].CGColor;
// 设置subLayer的圆角半径
subLayer.cornerRadius = 8;
// 设置subLayer的边框宽度
subLayer.borderWidth = 2;
// 设置subLayer的背景色
subLayer.borderColor = [UIColor blackColor].CGColor;
// 设置subLayer的阴影偏移(此处向右下角投下阴影)
subLayer.shadowOffset = CGSizeMake(4, 5);
// 设置subLayer的阴影的模糊程度(该属性值越大,阴影越模糊)
subLayer.shadowRadius = 1;
// 设置subLayer的阴影的颜色
subLayer.shadowColor = [UIColor blackColor].CGColor;
// 设置subLayer的阴影的透明度
subLayer.shadowOpacity = 0.8;
// 设置subLayer的大小和位置
subLayer.frame = CGRectMake(30, 30, 120, 160);
// 将subLayer添加到该视图控制器所显示的UIView上的CALayer
[self.view.layer addSublayer:subLayer];
// 再创建一个CALayer对象
CALayer *subLayer2 = [CALayer layer];
// 设置该CALayer的边框、阴影、大小、位置等属性
subLayer2.cornerRadius = 8;
subLayer2.borderWidth = 2;
subLayer2.borderColor = [UIColor blackColor].CGColor;
subLayer2.shadowOffset = CGSizeMake(4, 5);
subLayer2.shadowRadius = 1;
subLayer2.shadowColor = [UIColor blackColor].CGColor;
subLayer2.shadowOpacity = 0.8;
subLayer2.masksToBounds = YES;//需要注意的是代码中绘制图片圆形裁切效果时如果不设置masksToBounds是无法显示圆形,但是对于其他图形却没有这个限制。原因就是当绘制一张图片到图层上的时候会重新创建一个图层添加到当前图层,这样一来如果设置了圆角之后虽然底图层有圆角效果,但是子图层还是矩形,只有设置了masksToBounds为YES让子图层按底图层剪切才能显示圆角效果。同样的,使用UIImageView的layer设置圆角后图片无法显示圆角,只有设置masksToBounds才能出现效果,也是类似的问题。
subLayer2.frame = CGRectMake(170, 30, 120, 160);
// 将subLayer2添加到该视图控制器所显示的UIView上的CALayer
[self.view.layer addSublayer:subLayer2];
//-------------使用CALayer显示图片--------------
// 再创建一个CALayer对象
CALayer *imageLayer = [CALayer layer];
// 设置该imageLayer显示的图片
imageLayer.contents = (id)[[UIImage imageNamed:@"ptjShare"] CGImage];
// 设置iamgeLayer的大小和位置。
imageLayer.frame = subLayer2.bounds;
// 将imageLayer添加到subLayer2中
[subLayer2 addSublayer:imageLayer];
//--------------自定义CALayer的绘制内容--------------
// 再创建一个CALayer对象
CALayer *customDrawn = [CALayer layer];
// 设置CALayer的委托对象,该委托对象负责该CALayer的绘制
customDrawn.delegate = self;
customDrawn.backgroundColor = [UIColor greenColor].CGColor;
customDrawn.frame = CGRectMake(30, 220, 260, 210);
customDrawn.shadowOffset = CGSizeMake(0, 3);
customDrawn.shadowRadius = 5.0;
customDrawn.shadowColor = [UIColor blackColor].CGColor;
customDrawn.shadowOpacity = 0.8;
customDrawn.cornerRadius = 10.0;
customDrawn.borderColor = [UIColor blackColor].CGColor;
customDrawn.borderWidth = 2.0;
customDrawn.masksToBounds = YES;
[self.view.layer addSublayer:customDrawn];
// 必须有这行,这行才会通知CALayer调用delegate的drawLayer方法
[customDrawn setNeedsDisplay];
[super viewDidLoad];
}
// 重写该方法为CALayer绘制自定义内容.通过代理方法进行图层绘图只要指定图层的代理,然后在代理对象中重写-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx方法即可。需要注意这个方法虽然是代理方法但是不用手动实现CALayerDelegate,因为CALayer定义中给NSObject做了分类扩展,所有的NSObject都包含这个方法。另外设置完代理后必须要调用图层的setNeedDisplay方法,否则绘制的内容无法显示。
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context {
UIColor* bgColor = [UIColor colorWithPatternImage:
[UIImage imageNamed:@"ptjShare"]];
// 设置绘图的背景色
CGContextSetFillColorWithColor(context, bgColor.CGColor);
// 填充一个椭圆
CGContextFillEllipseInRect(context, CGRectMake(20 , 20 , 100 , 100));
//该方法负责绘制圆角矩形
CGContextAddRoundRect(context, 150, 20, 100, 60, 5);
CGContextFillPath(context);
CGContextSetRGBStrokeColor(context, 1, 1, 0, 1);
CGContextStrokePath(context);
CGContextFillPath(context);
}
@end
效果图为: