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 ...
随机推荐
- CodeMixerPro工具,完美替代ChaosTool,iOS添加垃圾代码工具,代码混淆工具,代码生成器,史上最好用的垃圾代码添加工具,自己开发的小工具
新工具 ProjectTool 已上线 这是一款快速写白包工具,秒级别写H5游戏壳包,可视化操作,极易使用,支持Swift.Objecive-C双语言 扣扣交流群:811715780 进入 Proje ...
- Mol. Cell. Proteomics | 癌细胞衍生的小细胞外囊体通过促进HGF-Met途径促进受体细胞转移
题目:Cancer cell derived small extracellular vesicles contribute to recipient cell metastasis through ...
- 为什么Mysql的常用引擎都默认使用B+树作为索引?
一.前言 为了讲清楚这个问题,我们要先了解什么是索引. 我记得刚刚学习数据库的时候,老师喜欢用书本的目录来类比数据库的索引,并告诉我们索引能够像目录一样,让我们更快地找到想要找到的数据. 如果是第一次 ...
- 利用Docker手动构建WebLogic镜像的步骤
info 我的Docker环境信息如下: [root@localhost ~]# docker info -f " OSType: {{.OperatingSystem}} {{.Archi ...
- vue 拖拽框架 draggable
直接使用 npm i -S vuedraggable 页面使用 <template> <div class="addProduct"> <el-d ...
- leetcode 签到 914. 卡牌分组
题目 给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌. 组内所有的牌上都写着相同的整数. 仅当你可选的 X ...
- HDU - 1503 最长公共子序列记录路径
题意:先给两个水果的名字然后得出一个最短的序列包含这两个词. 思路:我一开始的思路是先求出最长公共子序列,然后做一些处理将其他的部分输出来:两种水果的字符串和最长公共子序列的字符串这三个字符串做对比, ...
- Jenkins打造多分支流水线指南
overview: 多分支工作流程带来了以下几个关键能力: 在代码仓库中,每个新分支都有自己单独的工作流水线(job). 每个工作流水线都记录了对应分支的构建和变更历史. 可以自定义设置流水线随着分支 ...
- list容器排除重复单词的程序
#include<iostream> #include<fstream> #include<string> #include<algorithm> #i ...
- Python 程序慢的像蜗牛,我该怎么办?
1. “一猿小讲”的风格就是多元化,偶尔会真情吐露一下程序猿的内心:偶尔也结合自己的经历畅聊一些经验杂谈:其中也不乏幽默风趣的技术故事.分享是件快乐的事情,工作之余,有时间我就尽力多码字,多推几篇文章 ...