Quartz2D使用(图形上下文栈)

Quartz2D使用(图形上下文栈)

一、qurza2d是怎么将绘图信息和绘图的属性绘制到图形上下文中去的?

说明:

新建一个项目,自定义一个view类和storyboard关联后,重写该类中的drowrect方法。

画线的三个步骤:

(1)获取上下文

(2)绘图

(3)渲染

要求:画两条单独的线

代码和效果图:

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //获取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //绘图
 6     //第一条线
 7     CGContextMoveToPoint(ctx, 20, 100);
 8     CGContextAddLineToPoint(ctx, 100, 320);
 9
10     //第二条线
11     CGContextMoveToPoint(ctx, 40, 200);
12     CGContextAddLineToPoint(ctx, 80, 100);
13     //渲染
14     CGContextStrokePath(ctx);
15
16 }

效果图:

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

代码和效果图(发现第二条线也被渲染成第一条线的样式和状态)

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //获取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //绘图
 6     //第一条线
 7     CGContextMoveToPoint(ctx, 20, 100);
 8     CGContextAddLineToPoint(ctx, 100, 320);
 9
10     //设置第一条线的状态
11     //设置线条的宽度
12     CGContextSetLineWidth(ctx, 12);
13     //设置线条的颜色
14     [[UIColor brownColor]set];
15     //设置线条两端的样式为圆角
16     CGContextSetLineCap(ctx,kCGLineCapRound);
17     //对线条进行渲染
18     CGContextStrokePath(ctx);
19
20     //第二条线
21     CGContextMoveToPoint(ctx, 40, 200);
22     CGContextAddLineToPoint(ctx, 80, 100);
23     //渲染
24     CGContextStrokePath(ctx);
25
26 }

效果图:

新的需求:要让两条线的颜色不一样,要求第二条线变成原版的样子。要达到上面的要求,有以下几种做法:

第一种做法:

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

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //获取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //绘图
 6     //第一条线
 7     CGContextMoveToPoint(ctx, 20, 100);
 8     CGContextAddLineToPoint(ctx, 100, 320);
 9
10     //设置第一条线的状态
11     //设置线条的宽度
12     CGContextSetLineWidth(ctx, 12);
13     //设置线条的颜色
14     [[UIColor brownColor]set];
15     //设置线条两端的样式为圆角
16     CGContextSetLineCap(ctx,kCGLineCapRound);
17     //对线条进行渲染
18     CGContextStrokePath(ctx);
19
20     //第二条线
21     CGContextMoveToPoint(ctx, 40, 200);
22     CGContextAddLineToPoint(ctx, 80, 100);
23
24     //清空状态
25     CGContextSetLineWidth(ctx, 1);
26     [[UIColor blackColor]set];
27     CGContextSetLineCap(ctx,kCGLineCapButt);
28
29     //渲染
30     CGContextStrokePath(ctx);
31
32 }

第二种做法:

把第一条线从开始绘制到渲染的代码剪切到第二条线渲染完成之后,这样先绘制并渲染了第一条线,该线并没有对绘制信息进行过设置,显示出来的第二条线即位系统默认的效果。

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //获取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //绘图
 6
 7     //第二条线
 8     CGContextMoveToPoint(ctx, 40, 200);
 9     CGContextAddLineToPoint(ctx, 80, 100);
10
11     //清空状态
12     //    CGContextSetLineWidth(ctx, 1);
13     //    [[UIColor blackColor]set];
14
15     //    CGContextSetLineCap(ctx,kCGLineCapButt);
16
17     //渲染
18     CGContextStrokePath(ctx);
19
20     //第一条线
21     CGContextMoveToPoint(ctx, 20, 100);
22     CGContextAddLineToPoint(ctx, 100, 320);
23
24     //设置第一条线的状态
25     //设置线条的宽度
26     CGContextSetLineWidth(ctx, 12);
27     //设置线条的颜色
28     [[UIColor brownColor]set];
29     //设置线条两端的样式为圆角
30     CGContextSetLineCap(ctx,kCGLineCapRound);
31     //对线条进行渲染
32     CGContextStrokePath(ctx);
33 }

两种方式完成的效果相同:

但是有的情况下,必须要先画第一条线再画第二条线,要求在交叉部分,第二条线盖在第一条线的上面。如果要求是这样,那么只能使用第一种做法,但是如果现在有新的需求,要求在这个基础上再画两条线,那就需要清空ctx中的状态很多次,很麻烦。为了解决这个问题,下面给大家介绍图形上下文栈。

二、绘图的完整过程

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

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

如图:

     

说明:这些示意图和本文中的程序代码块,不具备一一对应关系,只是为了说明绘图的完整过程。

调用渲染方法的时候,把绘制图形区域已经画好的图形直接显示到view上,就是我们看到的样子了。

如图:

   

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

参考代码:

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //获取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //绘图
 6     //第一条线
 7     CGContextMoveToPoint(ctx, 20, 100);
 8     CGContextAddLineToPoint(ctx, 100, 320);
 9
10     //设置第一条线的状态
11     //设置线条的宽度
12     CGContextSetLineWidth(ctx, 12);
13     //设置线条的颜色
14     [[UIColor brownColor]set];
15     //设置线条两端的样式为圆角
16     CGContextSetLineCap(ctx,kCGLineCapRound);
17     //对线条进行渲染
18     CGContextStrokePath(ctx);
19
20     //第二条线
21     CGContextMoveToPoint(ctx, 40, 200);
22     CGContextAddLineToPoint(ctx, 80, 100);
23     //渲染
24     CGContextStrokePath(ctx);
25 }

如果清空了状态,则在渲染之前,在绘制图形区域对第二条线进行绘制的时候,会去查找当前的绘图信息(已经更改——清空),根据绘图信息对第二条线进行绘制,调用渲染方法的时候把第二条线显示到view上。

参考代码:

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //获取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //绘图
 6     //第一条线
 7     CGContextMoveToPoint(ctx, 20, 100);
 8     CGContextAddLineToPoint(ctx, 100, 320);
 9
10     //设置第一条线的状态
11     //设置线条的宽度
12     CGContextSetLineWidth(ctx, 12);
13     //设置线条的颜色
14     [[UIColor brownColor]set];
15     //设置线条两端的样式为圆角
16     CGContextSetLineCap(ctx,kCGLineCapRound);
17     //对线条进行渲染
18     CGContextStrokePath(ctx);
19
20     //第二条线
21     CGContextMoveToPoint(ctx, 40, 200);
22     CGContextAddLineToPoint(ctx, 80, 100);
23
24     //清空状态
25     CGContextSetLineWidth(ctx, 1);
26     [[UIColor blackColor]set];
27     CGContextSetLineCap(ctx,kCGLineCapButt);
28
29     //渲染
30     CGContextStrokePath(ctx);
31 }

三、图形上下文栈

1.简单说明

在获取图形上下文之后,通过

CGContextSaveGState(ctx);

方法,把当前获取的上下文拷贝一份,保存一份最纯洁的图形上下文。

在画第二条线之前,使用CGContextRestoreGState(ctx);方法,还原开始的时候保存的那份最纯洁的图形上下文。

代码:

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //获取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //保存一份最初的图形上下文
 6     CGContextSaveGState(ctx);
 7
 8     //绘图
 9     //第一条线
10     CGContextMoveToPoint(ctx, 20, 100);
11     CGContextAddLineToPoint(ctx, 100, 320);
12
13     //设置第一条线的状态
14     //设置线条的宽度
15     CGContextSetLineWidth(ctx, 12);
16     //设置线条的颜色
17     [[UIColor brownColor]set];
18     //设置线条两端的样式为圆角
19     CGContextSetLineCap(ctx,kCGLineCapRound);
20     //对线条进行渲染
21     CGContextStrokePath(ctx);
22
23     //还原开始的时候保存的那份最纯洁的图形上下文
24     CGContextRestoreGState(ctx);
25     //第二条线
26     CGContextMoveToPoint(ctx, 40, 200);
27     CGContextAddLineToPoint(ctx, 80, 100);
28
29     //清空状态
30 //    CGContextSetLineWidth(ctx, 1);
31 //    [[UIColor blackColor]set];
32 //    CGContextSetLineCap(ctx,kCGLineCapButt);
33
34     //渲染
35     CGContextStrokePath(ctx);
36 }

2.图形上下文栈机制

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

画第二条线的时候,去图形上下文栈中取出栈顶的绘图信息,作为第二条线的状态信息,第二条线的状态信息也是据此(最初保存的那份图形上下文)进行绘制。

          

注意:在栈里保存了几次,那么就可以取几次(比如不能保存了1次,取两次,在取第二次的时候,栈里为空会直接挂掉)。

时间: 2024-11-03 21:22:16

Quartz2D使用(图形上下文栈)的相关文章

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

iOS开发UI篇-Quartz2D使用(图形上下文栈) 一.qurza2d是怎么将绘图信息和绘图的属性绘制到图形上下文中去的? 说明: 新建一个项目,自定义一个view类和storyboard关联后,重写该类中的drowrect方法. 画线的三个步骤: (1)获取上下文 (2)绘图 (3)渲染 要求:画两条单独的线 代码和效果图: 1 - (void)drawRect:(CGRect)rect 2 { 3 //获取上下文 4 CGContextRef ctx=UIGraphicsGetCurre

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

转自:http://www.cnblogs.com/wendingding/p/3782489.html 一.qurza2d是怎么将绘图信息和绘图的属性绘制到图形上下文中去的? 说明: 新建一个项目,自定义一个view类和storyboard关联后,重写该类中的drowrect方法. 画线的三个步骤: (1)获取上下文 (2)绘图 (3)渲染 要求:画两条单独的线 代码和效果图: 1 - (void)drawRect:(CGRect)rect 2 { 3 //获取上下文 4 CGContextR

猫猫学IOS(三十一)UI之Quartz2D图形上下文栈

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 首先,前面博客说过.qurza2d的上下文中有绘图信息和绘图的属性. 但是他是怎么绘制到上下午中的呢? 我们画图时候一半会用这三个步骤: (1)获取上下文 (2)绘图 (3)渲染 这里引申出来一个问题,画两条线的时候,是怎么工作呢? 画两条相交的线 设置线段的宽度:两头为圆形,颜色等. 代码: - (void)drawRect

Quartz2d 画饼状图 图形上下文栈 矩阵操作 裁剪圆角图片

画饼状图 - (void)drawRect:(CGRect)rect { // Drawing code // 需求:根据sections的数据,绘制多个扇形 // 1.获取上下文(Layer Graphics Context) CGContextRef ctx = UIGraphicsGetCurrentContext(); // 2.根据sections的个数,计算扇形的起始和结束位置来画扇形 NSInteger count = self.sections.count; // 如果没有数据,

Quartz 2D 图形上下文栈 矩阵 裁剪

Quartz 2D 图形上下文栈  矩阵 1 // 2 // DJVIew.m 3 // 图形上下文栈 4 // 5 // Created by zjj on 15/6/30. 6 // Copyright (c) 2015年 zjj. All rights reserved. 7 // 8 9 #import "DJVIew.h" 10 11 @implementation DJVIew 12 13 - (void)drawRect:(CGRect)rect 14 { 15 CGCo

iOS高级-QuartzCore框架-图形上下文栈、矩阵操作、裁剪、重绘(刷帧)

一.图形上下文栈1.自定义一个MJView,继承自UIView2.将默认View的Class设置为MJView3.实现drawRect:方法-(void)drawRect:(CGRect)rect{ //1.获得上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(): //将当前的ctx拷贝一份放到栈中 CGContextSaveGState(ctx): //设置绘图状态 CGContextSetLineWidth(ctx,10): [[UICo

ios图形上下文栈

1 - (void)drawRect:(CGRect)rect 2 { 3 // 获取上下文 4 CGContextRef ctx = UIGraphicsGetCurrentContext(); 5 6 // 保存一份最纯洁的图形上下文 7 // 调用一次该方法就会拷贝一个上下文到栈中,存几次就最多能调用几次 CGContextRestoreGState(ctx),如果存了一次,取第二次的时候就会报错 8 9 CGContextSaveGState(ctx); 10 //CGContextSa

IOS 图形上下文栈

- (void)drawRect:(CGRect)rect { // 获取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 保存一份最纯洁的图形上下文 // 调用一次该方法就会拷贝一个上下文到栈中 CGContextSaveGState(ctx); //CGContextSaveGState(ctx); // 第一条线 // 利用图形上下文保存绘图信息 CGContextMoveToPoint(ctx, 150, 20); CGCo

【iOS】Quartz2D图形上下文

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