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

一、自定义层的方法1

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

1.创建一个CALayer的子类

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

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

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

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

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

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

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

 1 #pragma mark 画一个矩形框
2 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
3 // 设置蓝色
4 CGContextSetRGBStrokeColor(ctx, 0, 0, 1, 1);
5 // 设置边框宽度
6 CGContextSetLineWidth(ctx, 10);
7
8 // 添加一个跟层一样大的矩形到路径中
9 CGContextAddRect(ctx, layer.bounds);
10
11 // 绘制路径
12 CGContextStrokePath(ctx);
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. 【最短路】【Heap-dijkstra】Gym - 101147B - Street

    按题意把图建出来跑最短路就行了.注意遮挡不会影响答案,所以不必考虑,因为走直线经过遮挡的时候,一定不会比答案更优. #include<cstdio> #include<algorit ...

  2. 【并查集】bzoj1015 [JSOI2008]星球大战starwar

    倒着处理删点,就变成了加点,于是并查集. #include<cstdio> using namespace std; #define N 400001 int fa[N],kill[N], ...

  3. 计算数字出现的次数 Exercise07_03

    import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年下半年 * 题目:计算数字出现的次数 * */ public class Exercise0 ...

  4. 触摸事件onTouchListener

    1.效果图: (1)MainAcivity.java package com.example.app3; import android.content.DialogInterface; import ...

  5. iOS 10 资料整理笔记

    1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大改重构,这让开发者也体会到UserN ...

  6. 【Linux】ubuntu或linux网卡配置/etc/network/interfaces

    转自:http://gfrog.net/2008/01/config-file-in-debian-interfaces-1/   青蛙准备写一个系列文章,介绍一些Debian/Ubuntu里面常用的 ...

  7. TSynDBDataSet内存表

    TSynDBDataSet内存表 SynDBMidasVCL.pas TSynDBDataSet = class(TCustomClientDataSet) Props := TSQLDBSocket ...

  8. 位图(BitMap)索引

    前段时间听同事分享,偶尔讲起Oracle数据库的位图索引,顿时大感兴趣.说来惭愧,在这之前对位图索引一无所知,因此趁此机会写篇博文介绍下位图索引. 1. 案例 有张表名为table的表,由三列组成,分 ...

  9. 计算两个经纬度之间的距离(python算法)

    EARTH_REDIUS = 6378.137 def rad(d): return d * pi / 180.0 def getDistance(lat1, lng1, lat2, lng2): r ...

  10. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-如何查看错误代码

    一般模块出错会在Error中显示为TRUE,同时ErrorID中会有一个错误代码,下图所示就是出错之后的效果   在变量表中也可以看到,右击转成16进制查看   由于是NC模块出错,所以可以再NC的E ...