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

猫猫分享,必须精品

原创文章,欢迎转载。转载请注明:翟乃玉的博客

地址:http://blog.csdn.net/u013357243?viewmode=contents

首先,前面博客说过。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个。)第二条线的状态信息也是据此进行绘制。

(栈的特点,先进后出)

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

时间: 2024-08-28 04:14:16

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

猫猫学IOS(二十八)UI之Quartz2D简单介绍

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents iOS开发UI篇-Quartz2D简单介绍 什么是Quartz2D Quartz 2D是?个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF 截图\裁剪图片 自定义UI控件 Quartz2D在iOS开发中的

猫猫学IOS(四)UI之半小时搞定Tom猫

话不多说 先上效果 项目源码素材下载地址: Tom猫游戏代码iOS 素材http://blog.csdn.net/u013357243/article/details/44457357 效果图 曾经风靡一时的tom猫其实制作起来那是叫一个相当的easy啊 功能全部实现,(关键是素材,没有素材的可以加我微信) 新手也可以很快的完成tom这个很拉轰的ios应用哦 做过android的我表示,android党默哀下把,那个做起来真心痛苦.... 然后呢你需要准备这些素材... 拖拽控件吧,因为这一个项

(素材_源码) 猫猫学IOS(五)UI之360等下载管理器九宫格UI

猫猫分享,必须精品 先看效果 代码学习地址: 猫猫学IOS(五)UI之360等下载管理器九宫格UI 猫猫学IOS(五)UI之360等下载管理器九宫格UI http://blog.csdn.net/u013357243/article/details/44486609 下载地址:http://download.csdn.net/detail/u013357243/8516817 ps1:有想要源码的可以加猫猫微信znycat QQ也可以:1764541256 --视频学习资料素材免费分析,哎自己一

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】Quartz2D图形上下文

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

Quartz2D使用(图形上下文栈)

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

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

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

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

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