AJ学IOS(31)UI之Quartz2D图形上下文栈
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图形上下文栈的更多相关文章
- AJ学IOS(28)UI之Quartz2D简单介绍
AJ分享,必须精品 iOS开发UI篇—Quartz2D简单介绍 什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : ...
- iOS开发UI之Quartz2D使用(绘制基本图形)
iOS开发UI篇—Quartz2D使用(绘制基本图形) 一.简单说明 图形上下文(Graphics Context):是一个CGContextRef类型的数据 图形上下文的作用:保存绘图信息.绘图状态 ...
- iOS开发UI篇—Quartz2D使用(绘制基本图形)
iOS开发UI篇—Quartz2D使用(绘制基本图形) 一.简单说明 图形上下文(Graphics Context):是一个CGContextRef类型的数据 图形上下文的作用:保存绘图信息.绘图状态 ...
- iOS开发UI篇—Quartz2D使用(图形上下文栈)
iOS开发UI篇—Quartz2D使用(图形上下文栈) 一.qurza2d是怎么将绘图信息和绘图的属性绘制到图形上下文中去的? 说明: 新建一个项目,自定义一个view类和storyboard关联后, ...
- iOS开发UI篇—Quartz2D使用(图形上下文栈
转自:http://www.cnblogs.com/wendingding/p/3782489.html 一.qurza2d是怎么将绘图信息和绘图的属性绘制到图形上下文中去的? 说明: 新建一个项目, ...
- iOS开发UI篇—Quartz2D简单使用(一)
iOS开发UI篇—Quartz2D简单使用(一) 一.画直线 代码: 1 // 2 // YYlineview.m 3 // 03-画直线 4 // 5 // Created by apple on ...
- iOS开发UI篇—Quartz2D简单介绍
iOS开发UI篇—Quartz2D简单介绍 一.什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\ ...
- iOS开发UI篇—Quartz2D简单使用(一)
iOS开发UI篇—Quartz2D简单使用(一) 一.画直线 代码: // // YYlineview.m // 03-画直线 // // Created by apple on 14-6-9. // ...
- iOS开发UI篇—Quartz2D使用(矩阵操作)
iOS开发UI篇—Quartz2D使用(矩阵操作) 一.关于矩阵操作 1.画一个四边形 通过设置两个端点(长和宽)来完成一个四边形的绘制. 代码: - (void)drawRect:(CGRect)r ...
随机推荐
- C++ 类的继承和派生
继承的优点:减少代码的冗余 提高代码的重用性 派生类定义格式: Class 派生类名 : 继承方式 基类名{ //派生类新增的数据成员和成员函数 }; class 子类: 继承方式 父类名{ //子类 ...
- c# 对SOAP返回XML字符串的解析方法
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP:Head ...
- 毫米波大规模阵列中的AOA估计
1.AOA估计在毫米波大规模MIMO中的重要性 在毫米波大规模MIMO的CSI估计中,AoA估计具有重要地位,主要原因归纳如下: 毫米波大规模MIMO 的信道具有空域稀疏性,可以简单通过AoA 和路径 ...
- innobackupex备份过程(有图有真相)
innobackupex命令构成: 1. Innobackupex内部封装了xtrabackup和mysqldump命令: 2. Xtrabackup是用来备份innoDB表的,内部实现对innoDB ...
- 硬货 | 手把手带你构建视频分类模型(附Python演练))
译者 | VK 来源 | Analytics Vidhya 概述 了解如何使用计算机视觉和深度学习技术处理视频数据 我们将在Python中构建自己的视频分类模型 这是一个非常实用的视频分类教程,所以准 ...
- 从本地方法栈看到jni调用
我们都知道java虚拟机所管理的内存区域包括方法区,堆,虚拟机栈,本地方法栈,程序计数器. 在<深入理解java虚拟机>中,周志明老师对虚拟机栈进行了讲解,但是对本地方法栈却一笔带过.今天 ...
- Thread -- Volatile
1,可见性也就是说一旦某个线程修改了该被volatile修饰的变量,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,可以立即获取修改之后的值. 在Java中为了加快程序的运行效率,对一些变 ...
- jsp学习笔记day1
一.jsp简介 JSP全称Java Server Pages,是一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以<%开头以%>结束. JSP是一种Java ...
- [tyvj2032]升降梯上<dp&spfa>
题目背景 开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道,映入眼帘的是一条直通塔顶的轨道.一辆停在轨道底部的电梯.和电梯内一杆控制电梯升降的巨大手柄. 题目描述 Nescafe 之 ...
- IE,Google Chrome等浏览器,调试模式在控制台可以手动调用页面的方法来调试
IE,Google Chrome等浏览器,调试模式在控制台可以手动调用页面的方法来调试,这种方式也可以进断点.