自定义层,其实就是在层上绘图,一共有2种方法,下面详细介绍一下。

一、自定义层的方法1

方法描述:创建一个CALayer的子类,然后覆盖drawInContext:方法,使用Quartz2D API进行绘图

1.创建一个CALayer的子类

2.在.m文件中覆盖drawInContext:方法,在里面绘图

  1. 1 @implementation MJLayer
  2. 2
  3. 3 #pragma mark 绘制一个实心三角形
  4. 4 - (void)drawInContext:(CGContextRef)ctx {
  5. 5 // 设置为蓝色
  6. 6 CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);
  7. 7
  8. 8
  9. 9 // 设置起点
  10. 10 CGContextMoveToPoint(ctx, 50, 0);
  11. 11 // 从(50, 0)连线到(0, 100)
  12. 12 CGContextAddLineToPoint(ctx, 0, 100);
  13. 13 // 从(0, 100)连线到(100, 100)
  14. 14 CGContextAddLineToPoint(ctx, 100, 100);
  15. 15 // 合并路径,连接起点和终点
  16. 16 CGContextClosePath(ctx);
  17. 17
  18. 18 // 绘制路径
  19. 19 CGContextFillPath(ctx);
  20. 20 }
  21. 21
  22. 22 @end

3.在控制器中添加图层到屏幕上

  1. 1 MJLayer *layer = [MJLayer layer];
  2. 2 // 设置层的宽高
  3. 3 layer.bounds = CGRectMake(0, 0, 100, 100);
  4. 4 // 设置层的位置
  5. 5 layer.position = CGPointMake(100, 100);
  6. 6 // 开始绘制图层
  7. 7 [layer setNeedsDisplay];
  8. 8 [self.view.layer addSublayer:layer];

注意第7行,需要调用setNeedsDisplay这个方法,才会触发drawInContext:方法的调用,然后进行绘图

二、自定义层的方法2

方法描述:设置CALayer的delegate,然后让delegate实现drawLayer:inContext:方法,当CALayer需要绘图时,会调用delegate的drawLayer:inContext:方法进行绘图。

* 这里要注意的是:不能再将某个UIView设置为CALayer的delegate,因为UIView对象已经是它内部根层的delegate,再次设置为其他层的delegate就会出问题。UIView和它内部CALayer的默认关系图:

1.创建新的层,设置delegate,然后添加到控制器的view的layer中

  1. 1 CALayer *layer = [CALayer layer];
  2. 2 // 设置delegate
  3. 3 layer.delegate = self;
  4. 4 // 设置层的宽高
  5. 5 layer.bounds = CGRectMake(0, 0, 100, 100);
  6. 6 // 设置层的位置
  7. 7 layer.position = CGPointMake(100, 100);
  8. 8 // 开始绘制图层
  9. 9 [layer setNeedsDisplay];
  10. 10 [self.view.layer addSublayer:layer];

* 在第3行设置了CALayer的delegate,这里的self是指控制器

* 注意第9行,需要调用setNeedsDisplay这个方法,才会通知delegate进行绘图

2.让CALayer的delegate(前面设置的是控制器)实现drawLayer:inContext:方法

  1. 1 #pragma mark 画一个矩形框
  2. 2 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
  3. 3 // 设置蓝色
  4. 4 CGContextSetRGBStrokeColor(ctx, 0, 0, 1, 1);
  5. 5 // 设置边框宽度
  6. 6 CGContextSetLineWidth(ctx, 10);
  7. 7
  8. 8 // 添加一个跟层一样大的矩形到路径中
  9. 9 CGContextAddRect(ctx, layer.bounds);
  10. 10
  11. 11 // 绘制路径
  12. 12 CGContextStrokePath(ctx);
  13. 13 }

三、其他

1.总结

无论采取哪种方法来自定义层,都必须调用CALayer的setNeedsDisplay方法才能正常绘图。

2.UIView的详细显示过程

* 当UIView需要显示时,它内部的层会准备好一个CGContextRef(图形上下文),然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法

* 平时在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入层的CGContextRef中,然后被拷贝至屏幕

 
 

李洪强-CALayer4-自定义层的更多相关文章

  1. 李洪强iOS经典面试题35-按层遍历二叉树的节点

    李洪强iOS经典面试题35-按层遍历二叉树的节点 问题 给你一棵二叉树,请按层输出其的节点值,即:按从上到下,从左到右的顺序. 例如,如果给你如下一棵二叉树:    3   / \  9  20   ...

  2. 李洪强iOS经典面试题144-数据存储

    李洪强iOS经典面试题144-数据存储   数据存储 sqlite中插入特殊字符的方法和接收到处理方法. 除'其他的都是在特殊字符前面加"/",而 ' -> '' .方法:k ...

  3. 李洪强iOS经典面试题143-绘图与动画

    李洪强iOS经典面试题143-绘图与动画   绘图与动画 CAAnimation的层级结构 CAPropertyAnimation是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使 ...

  4. 李洪强iOS经典面试题140-UI

    李洪强iOS经典面试题140-UI   UI viewcontroller的一些方法的说明viewDidLoad,viewWillDisappear, viewWillAppear方法的 顺序和作用? ...

  5. 李洪强iOS经典面试题上

    李洪强iOS经典面试题上     1. 风格纠错题 修改完的代码: 修改方法有很多种,现给出一种做示例: // .h文件 // http://weibo.com/luohanchenyilong/ / ...

  6. 李洪强经典面试题152-Runtime

    李洪强经典面试题152-Runtime   Runtime Runtime是什么 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码, ...

  7. 李洪强经典面试题145-Runloop

    李洪强经典面试题145-Runloop   Runloop 什么是 Runloop? 从字面上讲就是运行循环. 它内部就是do-while循环,在这个循环内部不断地处理各种任务. 一个线程对应一个Ru ...

  8. 李洪强iOS经典面试题141-报错警告调试

    李洪强iOS经典面试题141-报错警告调试   报错警告调试 你在实际开发中,有哪些手机架构与性能调试经验 刚接手公司的旧项目时,模块特别多,而且几乎所有的代码都写在控制器里面,比如UI控件代码.网络 ...

  9. 李洪强iOS经典面试题137-内存管理

      内存管理 ARC处理原理 ARC是Objective-C编译器的特性,而不是运行时特性或者垃圾回收机制,ARC所做的只不过是在代码编译时为你自动在合适的位置插入release或autoreleas ...

随机推荐

  1. 【小笔记】斜率优化的结论(WC)

  2. 在xcode6中使用矢量图(iPhone6置配UI)

    转载出处:http://blog.xoneday.com ios应用程序是一个图像主导的产品.在开发一个应用程序时,你需要各种尺寸的图标,你需要为每个图像文件制作一个@1x尺寸和一个@2x尺寸.这样你 ...

  3. Matlab图形中输入希腊字母

    xlabel('\beta'); ylabel('\delta'); 希腊字母等特殊字符用 \加拼音 如: α \alpha β \beta γ \gamma θ \theta Θ \Theta Г ...

  4. 继承了母板页的onload的事件

    这段时间实在是太忙了, 现借国庆放假之际,把一些问题写一下, 不久前,有位网友问我继承了母版页的页面要加载body的onload事件如何加载,我以前刚开始用母板的时候也碰到过这种问题, 直接是用JAV ...

  5. java直接跳转页面

    public static String genForwardHtml(String url, Map<String, String> parameters, String charset ...

  6. 如何判断一个请求是不是ajax请求

    原文:http://blog.csdn.net/easy_is_good/article/details/53609057 public boolean isAjaxRequest(HttpServl ...

  7. 直接拿来用!最火的iOS开源项目(二)

    每一次的改变总意味着新的开始.”这句话用在iOS上可谓是再合适不过的了.GitHub上的iOS开源项目数不胜数,iOS每一次的改变,总会引发iOS开源项目的演变,从iOS 1.x到如今的iOS 7,有 ...

  8. DELPHI MAKEWORD的用法

    WORD MAKEWORD(    BYTE bLow,  // low-order byte of short value    BYTE bHigh  // high-order byte of ...

  9. Tempter of the Bone——DFS(王道)

    Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However, ...

  10. oracle 存储过程的一个小问题

    在存储过程中,一般不能直接使用DDL语句,需要借助 execute immediate方法,否则可能报 pls00103错误 例子如下: create or replace procedure rt_ ...