CALayer之绘图

标签: quartz
266人阅读 评论(0) 收藏 举报

在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

效果图为:

这里写图片描述

查看评论

iOS8开发技术(Swift版):核心绘图API

本课程主要介绍了iOS8中的核心绘图API,包括绘制直线、阴影、渐变、图像等。
  • 2015年07月05日 17:47

用CALayer绘图

在iOS中绘图,可以使用UIView,也可以使用CALayer。实际上,UIView也是由底层的CALayer完成绘制的工作 UIView和CALayer的关系每个UIView内部都有一个CALay...
  • kyfxbl
  • kyfxbl
  • 2016-02-06 22:42:26
  • 880

iOS开发系列-动画绘图CALayer

代码下载地址:https://github.com/wwpeter/WW-MotionDemo.git 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iO...
  • super_man_ww
  • super_man_ww
  • 2016-05-06 13:18:51
  • 1565

CALayer简单应用——渐变

#import "ViewController.h" @interface ViewController () @property (nonatomic, strong) CALayer *ima...
  • ycz19930423
  • ycz19930423
  • 2015-12-21 19:31:44
  • 734

CALayer绘图

通过CALayer的代理方法进行绘图,可用于社交app的头像应用
  • u010606986
  • u010606986
  • 2015-03-06 15:47:13
  • 468

ios-day18-02(通过CALayer做出跟UIImageView一样的效果、UIView和CALayer如何选择)

下面的效果图是用CALayer做出跟UIImageView一样的效果: 源码下载地址:http://download.csdn.net/detail/liu537192/8553199 核...
  • liu537192
  • liu537192
  • 2015-04-01 11:11:10
  • 535

CALayer之CAShapeLayer

关于CAShapeLayer 内容大纲: CAShapeLayer简介 贝塞尔曲线与CAShapeLayer的关系 strokeStart和strokeEnd 动画 用CAShapeLayer实现进度...
  • LXL_815520
  • LXL_815520
  • 2016-04-13 15:10:17
  • 1076

绘图性能优化

总结总结 异步绘图 CALayer有一个叫做drawsAsynchronously的属性,这似乎是一个解决所有问题的高招。注意,尽管这可能提升性能,但也可能让事情变慢。 ...
  • jks456
  • jks456
  • 2015-11-03 16:13:40
  • 256

IOS-swift 动画05 CALayer绘图动画

上一个例子中我们通过使用多个layer进行动画的展示 有些时候我们也需要通过Core Graphics绘图在一个layer上进行动画 (比较复杂的情况)大概步骤: 定义属性 使用 @NSManage...
  • baodongsheng2011
  • baodongsheng2011
  • 2016-05-23 18:34:47
  • 659

CALayer 异步绘制

UIKit的单线程天性意味着寄宿图通畅要在主线程上更新,这意味着绘制会打断用户交互,甚至让整个app看起来处于无响应状态。我们对此无能为力,但是如果能避免用户等待绘制完成就好多了。 针对这个问题,有...
  • bravegogo
  • bravegogo
  • 2016-04-04 16:37:23
  • 882
    个人资料
    持之以恒
    等级:
    访问量: 28万+
    积分: 4998
    排名: 7094
    最新评论