AJ分享,必须精品

首先,前面博客说过。qurza2d的上下文中有绘图信息和绘图的属性。
但是他是怎么绘制到上下午中的呢?

我们画图时候一半会用这三个步骤:
(1)获取上下文
(2)绘图
(3)渲染
这里引申出来一个问题,画两条线的时候,是怎么工作呢?

画两条相交的线

设置线段的宽度:两头为圆形,颜色等。

代码:

- (void)drawRect:(CGRect)rect
{
//获取上下文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//绘图
//第一条线
CGContextMoveToPoint(ctx, 30, 130);
CGContextAddLineToPoint(ctx, 250, 130); //设置第一条线的状态
//设置线条的宽度
CGContextSetLineWidth(ctx, 12);
//设置线条的颜色
[[UIColor redColor]set];
//设置线条两端的样式为圆角
CGContextSetLineCap(ctx,kCGLineCapRound);
//对线条进行渲染
CGContextStrokePath(ctx); //第二条线
CGContextMoveToPoint(ctx, 160, 30);
CGContextAddLineToPoint(ctx, 160, 200);
//渲染
CGContextStrokePath(ctx); }

这时候,我们发现,第二条我们并没有设置他的颜色和圆角等属性,但是他还是画上去了,因为他们共同用了一个上下文
CGContextRef ctx=UIGraphicsGetCurrentContext();

画两条相交的线,并且让第二条线段变成最初的样子

这里有两种做法

第一种:清空

在对第二条线进行设置的时候,清空它的状态

- (void)drawRect:(CGRect)rect
{
//获取上下文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//绘图
//第一条线
CGContextMoveToPoint(ctx, 30, 130);
CGContextAddLineToPoint(ctx, 250, 130); //设置第一条线的状态
//设置线条的宽度
CGContextSetLineWidth(ctx, 12);
//设置线条的颜色
[[UIColor redColor]set];
//设置线条两端的样式为圆角
CGContextSetLineCap(ctx,kCGLineCapRound);
//对线条进行渲染
CGContextStrokePath(ctx); //第二条线
CGContextMoveToPoint(ctx, 160, 30);
CGContextAddLineToPoint(ctx, 160, 200); //清空状态
CGContextSetLineWidth(ctx, 1);
[[UIColor blackColor]set];
CGContextSetLineCap(ctx,kCGLineCapButt); //渲染
CGContextStrokePath(ctx); }

第二种:调换顺序

先画第二条,然后画第一条。(记得画完第一个要渲染否则无效。)

- (void)drawRect:(CGRect)rect
{
//获取上下文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//绘图 //第二条线
CGContextMoveToPoint(ctx, 160, 30);
CGContextAddLineToPoint(ctx, 160, 200); //渲染
CGContextStrokePath(ctx); //第一条线
CGContextMoveToPoint(ctx, 30, 130);
CGContextAddLineToPoint(ctx, 250, 130); //设置第一条线的状态
//设置线条的宽度
CGContextSetLineWidth(ctx, 12);
//设置线条的颜色
[[UIColor redColor]set];
//设置线条两端的样式为圆角
CGContextSetLineCap(ctx,kCGLineCapRound);
//对线条进行渲染
CGContextStrokePath(ctx); //渲染
CGContextStrokePath(ctx); }

图形上下文栈:

上面两种方法产生的效果差不多,但是还是有略微的区别。
有的情况下,必须要先画第一条线再画第二条线,要求在交叉部分,第二条线盖在第一条线的上面。如果要求是这样,那么只能使用第一种做法,但是每次都清空,如果画的多了,非常麻烦。这里有个新的东东:图形上下文栈。

绘图的完整过程

程序启动,显示自定义的view。当程序第一次显示在我们眼前的时候,程序会调用drawRect:方法,在里面获取了图形上下文(在内存中拥有了),然后利用图形上下文保存绘图信息,可以理解为图形上下文中有一块区域用来保存绘图信息,有一块区域用来保存绘图的状态(线宽,圆角,颜色)。直线不是直接绘制到view上的,可以理解为在图形上下文中有一块单独的区域用来先绘制图形,当调用渲染方法的时候,再把绘制好的图形显示到view上去。

在绘制图形区域,会去保存绘图状态区域中查找对应的状态信息(线宽,圆角,颜色),然后在绘图区域把对第一条直线绘制完成。其实在渲染之前,就已经把直线在绘制图形区域画好了。
如图:

这些示意图和本文中的程序代码块,不具备一一对应关系,只是为了说明绘图的完整过程。
调用渲染方法的时候,把绘制图形区域已经画好的图形直接显示到view上,就是我们看到的样子了。
如图:

画第二条的时候,如果没有对绘图状态进行重新设置,那么可以发现画第一天线的时候使用的绘图状态还保存在图形上下文中,在第二条线进行渲染之前,会根据第一条线(上一份绘图状态)对第二条线进行相应的设置,渲染后把第二条线显示到屏幕上。

简单说明图形上下文栈

在获取图形上下文之后,通过 CGContextSaveGState(ctx); 方法,把当前获取的上下文拷贝一份,保存一份最纯洁的图形上下文。
在画第二条线之前,使用CGContextRestoreGState(ctx);方法,还原开始的时候保存的那份最纯洁的图形上下文。
代码

- (void)drawRect:(CGRect)rect
{
//获取上下文
CGContextRef ctx=UIGraphicsGetCurrentContext(); //保存一份最初的图形上下文
CGContextSaveGState(ctx); //绘图
//第一条线
CGContextMoveToPoint(ctx, 30, 130);
CGContextAddLineToPoint(ctx, 250, 130); //设置第一条线的状态
//设置线条的宽度
CGContextSetLineWidth(ctx, 12);
//设置线条的颜色
[[UIColor redColor]set];
//设置线条两端的样式为圆角
CGContextSetLineCap(ctx,kCGLineCapRound);
//对线条进行渲染
CGContextStrokePath(ctx); //还原开始的时候保存的那份最纯洁的图形上下文
CGContextRestoreGState(ctx); //第二条线
CGContextMoveToPoint(ctx, 160, 30);
CGContextAddLineToPoint(ctx, 160, 200); //渲染
CGContextStrokePath(ctx); }

这样就实现了第二条在第一条上面的图片,看效果:

图解图形上下文栈

画第一条线的时候,会把当前的图形上下文拷贝一份保存到图形上下文栈中。(栈中一个)

画第二条线的时候,去图形上下文栈中取出栈顶的绘图信息,作为第二条线的状态信息,(此时栈中一个被取还剩0个。)第二条线的状态信息也是据此进行绘制。
(栈的特点,先进后出)

注意:图形上下文栈里面保存几次就能取几次,不能存了一个你取俩,这样就崩了。

AJ学IOS(31)UI之Quartz2D图形上下文栈的更多相关文章

  1. AJ学IOS(28)UI之Quartz2D简单介绍

    AJ分享,必须精品 iOS开发UI篇—Quartz2D简单介绍 什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : ...

  2. iOS开发UI之Quartz2D使用(绘制基本图形)

    iOS开发UI篇—Quartz2D使用(绘制基本图形) 一.简单说明 图形上下文(Graphics Context):是一个CGContextRef类型的数据 图形上下文的作用:保存绘图信息.绘图状态 ...

  3. iOS开发UI篇—Quartz2D使用(绘制基本图形)

    iOS开发UI篇—Quartz2D使用(绘制基本图形) 一.简单说明 图形上下文(Graphics Context):是一个CGContextRef类型的数据 图形上下文的作用:保存绘图信息.绘图状态 ...

  4. iOS开发UI篇—Quartz2D使用(图形上下文栈)

    iOS开发UI篇—Quartz2D使用(图形上下文栈) 一.qurza2d是怎么将绘图信息和绘图的属性绘制到图形上下文中去的? 说明: 新建一个项目,自定义一个view类和storyboard关联后, ...

  5. iOS开发UI篇—Quartz2D使用(图形上下文栈

    转自:http://www.cnblogs.com/wendingding/p/3782489.html 一.qurza2d是怎么将绘图信息和绘图的属性绘制到图形上下文中去的? 说明: 新建一个项目, ...

  6. iOS开发UI篇—Quartz2D简单使用(一)

    iOS开发UI篇—Quartz2D简单使用(一) 一.画直线 代码: 1 // 2 // YYlineview.m 3 // 03-画直线 4 // 5 // Created by apple on ...

  7. iOS开发UI篇—Quartz2D简单介绍

    iOS开发UI篇—Quartz2D简单介绍 一.什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\ ...

  8. iOS开发UI篇—Quartz2D简单使用(一)

    iOS开发UI篇—Quartz2D简单使用(一) 一.画直线 代码: // // YYlineview.m // 03-画直线 // // Created by apple on 14-6-9. // ...

  9. iOS开发UI篇—Quartz2D使用(矩阵操作)

    iOS开发UI篇—Quartz2D使用(矩阵操作) 一.关于矩阵操作 1.画一个四边形 通过设置两个端点(长和宽)来完成一个四边形的绘制. 代码: - (void)drawRect:(CGRect)r ...

随机推荐

  1. 2019HECTF总结_web题

    奇怪的编码 ♭|§∮♯♭|§∮♬♭|§§♫♭|§∮§♭|§♩§♭|♯♬¶♭|§§♫♭|§§¶♭|♯¶§♭|♯¶♫♭|§∮♭♭|§§♫♭|§§♬♭|♯♬♪♭|♯¶♪♭|♯¶|♭|♯¶♯♭|♯♬♬♭|♯♬ ...

  2. Java容器的常见问题

    记录Java容器中的常见概念和原理 参考: https://github.com/wangzhiwubigdata/God-Of-BigData#三Java并发容器 https://blog.csdn ...

  3. django中基于python3.6使用容联发送短信

    一. Django基于python3.6使用容联发送短信流程 容联官方的python支持2.7版本,当我们python解释器采用3版本时,需要修改容联接口中的一些参数及方法. 首先去容联官网注册账号, ...

  4. Mysql数据库设置权限

    这里使用cmd窗口进行权限设置. 以管理员账号连接数据库 创建数据库 create database 数据库名字 default charset=utf8; 查看用户 select user,host ...

  5. cmdb客户端采集数据的完善

    file文件自己去拷贝(这里不提供) custom_settings.py import os BASEDIR = os.path.dirname(os.path.dirname(os.path.ab ...

  6. django中的缓存以及跨域

    django中的缓存 先来了解以下问题

  7. 【洛谷】P2444 [POI2000]病毒——AC自动机

    题目链接 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段, ...

  8. [ex-kmp] HDU 2019 Multi-University Training Contest 5-string matching

    string matching Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others ...

  9. CSS常用属性之选择器

    css选择器 序号 选择器 例子 例子描述 1 .class .intro 选择class="intro"的所有元素 2 #id #firstname 选择id="fir ...

  10. 字节码类库之Javassist

    Javassist优势 – 比反射开销小,性能高.–javassist性能高于反射,低于ASM运行时操作字节码可以让我们实现如下功能:– 动态生成 新的类– 动态改变某个类的结构 ( 添加 / 删除 ...