iOS_Quartz2D_ 基础

什么是Quartz 2D

1>Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac OS X系统(跨平台,纯C语言的),包含在Core Graphics框架中.

2> Quartz 2DAPI是纯C语言的.数据类型和函数基本都是以CG作为前缀.: CGContextRef, CGPathRef, CGContextStrokePath……

Quartz 2D能完成什么工作?

l1>绘制图形:线条,三角形,矩形,,,.

l2>绘制文字.

l3>绘制生成图片(图像).

l4>读取\生成PDF.

l5>截图\裁剪图片.

l6>自定义UI控件,如环形下载进度条等.

Quartz 2D绘图主要步骤:

l1>获取图形上下文”.

l2>图形上下文中添加路径.

l3>渲染.把图形上下文中的图形绘制到对应的设备上.

关于图形上下文CGContextRef中主要包含的信息:

l1>绘图路径(各种各样的图形).

l2>绘制状态(颜色,线宽,样式,旋转,缩放,平移,图片裁剪区域等).

l3>输出目标(绘制到什么地方去?UIView,图片, pdf,打印机等).





使用Quartz 2D绘图:

l1>绘图路径(各种各样的图形).

l2>绘制状态(颜色,线宽,样式,旋转,缩放,平移,图片裁剪区域等).

l3>输出目标(绘制到什么地方去UIView,图片, pdf,打印机等).

使用方式一直接调用Quartz2D的API进行绘图

l1>代码量稍大,功能全面.

l2>步骤如下.

步骤一获取绘图上下文

步骤二把图形绘制到绘图上下文中

步骤三把绘图上下文上的图形渲染到对应的设备上

使用方式二调用UIKit框架封装好的API进行绘图

l1>代码相对简单,只对部分Quartz2DAPI做了封装.比如:画图片,文字到控件上.

l2>对于没有封装的功能只能调用Quartz2D原生的API

DrawRect:方法介绍

l1.为什么向UIView上绘图,代码必须写到drawRect:方法中?

原因:因为只有在view的drawRect:方法中,才能正确的获取这个view的layer的图形上下文。

l2.drawRect:方法一定不要自己手动去调用。系统会自动在该调用的时候去调用这个方法。

请问:为什么不能手动去调用这个方法?

1>因为系统在调用drawRect:方法之前,会先创建一个和当前view相关的layer的图形上下文。这样的话,在drawRect:这个方法中就可以正确的获取相应的图形上下文,然后就可以进行绘图了。

2>如果手动去调用drawRect:方法,那么在调用drawRect:方法的时候,无法保证和当前view相关的layer的图形上下文已经创建,所以在drawRect:这个方法中就可能无法正确的获取相应的图形上下文,如果没有图形上下文,那么也就无法进行绘图。

l3.如果必须需要重绘的话,怎么办?

解答:如果必须要进行一次重新绘制,那么也不要直接调用drawRect:方法,而是去调用setNeedsDisplay或者setNeedsDisplayInRect:。这两个方法内部会先创建一个图形上下文对象,然后调用drawRect:方法。

l4.drawRect:方法是什么时候调用的?调用几次?

1>这个方法只在第一次显示view的时候调用一次

2>如果后续需要重新刷新这个view的显示,那么需要调用setNeedsDisplay或者setNeedsDisplayInRect:

3>或者是当前view进行重新绘制的时候就会调用drawRect:方法

l5.drawRect:方法中的参数rect指的是什么?

解答:当前绘图view的bounds。

l6.补充和注意点:

1> UIView内部有个layer(图层)属性,drawRect:方法中取得的是一个Layer Graphics Context,因此,绘制的东西其实是绘制到view的layer上去了.

2> UIView之所以能显示东西,完全是因为它内部的layer.

l7.UIView主要的两个功能是什么?

1>显示,为什么UIView可以显示内容,原因是UIView内部有一个layer,也就是说我们实际上向UIView中绘制的所有内容,其实最终都是画在了layer上.

2>监听事件.

案例一Quartz2D简单演练

展示效果:




请问:实现的步骤是什么?

第一步,在控制器的界面中拖入一个UIView控件,并将类型更改为自定义的类型,重写drawRect:方法进行绘图,此时绘制的图形会被渲染到控件的layer图层上.

第二步,绘制线条和三角形,使用Quartz 2D原生API来进行绘图.请问:有哪3个步骤?.

1>获得图形上下文

2>拼接路径

3>渲染

第三步,使用UIKit框架封装好的UIBezierPath对象来进行绘制图形.请问:有哪几个步骤?.

1>获得图形上下文

2>创建一个UIBezierPath对象(路径对象)

3>向UIBezierPath对象中添加若干个路径

4>把UIBezierPath添加到对应的图形上下文中

5>渲染

第四步,绘制矩形框.

//代码实现使用Quartz2D原生API来进行绘图

------------------------------HMDrawingView.m------------------------------

//

Only override drawRect: if you perform custom drawing.An empty implementation

adversely affects performance during animation.

//仅仅只应该在自定义绘图的时候重写drawRect:该方法.如果仅仅重写该方法,而不执行任何代码,那么在执行动画期间会产生一些不利的影响.

```

- (void)drawRect:(CGRect)rect {

// 1.获取图形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

/**********路径信息**********/

// 2.向图形上下文中添加路径-绘制一个三角形

// 2.1移动到一个起始点

CGContextMoveToPoint(ctx,50,50);

// 2.2添加一条线到某个点

CGContextAddLineToPoint(ctx,150,50);

// 2.3再添加一条线段

CGContextAddLineToPoint(ctx,50,200);

// 2.4再添加一条线段

//CGContextAddLineToPoint(ctx, 50, 50);

// 2.5关闭路径

CGContextClosePath(ctx);

//在添加一个新的线段

// 2.6移动到一个新的起点-绘制一条线

CGContextMoveToPoint(ctx,50,260);

// 2.7添加一条线段

CGContextAddLineToPoint(ctx,260,260);

/**********状态信息**********/

//设置线条的状态

CGContextSetLineWidth(ctx,20);

//设置线头样式

CGContextSetLineCap(ctx,kCGLineCapRound);

//线段连接处的样式

CGContextSetLineJoin(ctx,kCGLineJoinRound);

//设置线条的颜色

[[UIColorredColor]setStroke];//空心

[[UIColoryellowColor]setFill];//实心

//设置stroke & fill颜色

[[UIColorblueColor]set];

// 3.渲染

CGContextStrokePath(ctx);//空心渲染

CGContextFillPath(ctx);//实心渲染

}

```

//代码实现使用UIKit框架封装好的UIBezierPath对象来进行绘制图形

------------------------------HMDrawingView.m------------------------------

```

- (void)drawRect:(CGRect)rect {

// 1.获取图形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

// 2.创建一个UIBezierPath对象(路径对象)

UIBezierPath*path = [UIBezierPathbezierPath];

// 3.向UIBezierPath对象中添加若干个路径

[pathmoveToPoint:CGPointMake(50,50)];

[pathaddLineToPoint:CGPointMake(150,50)];

[pathaddLineToPoint:CGPointMake(50,150)];

[pathclosePath];

// 4.把UIBezierPath添加到对应的图形上下文中

CGContextAddPath(ctx, path.CGPath);

// 5.渲染

CGContextStrokePath(ctx);

}

//步骤四绘制“矩形框”使用Quartz 2D原生API来进行绘图

- (void)drawRect:(CGRect)rect {

// 1.获取图形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

// 2.绘制矩形框

CGContextAddRect(ctx,CGRectMake(50,50,100,100));

// 3.渲染

CGContextStrokePath(ctx);

}

//步骤四使用UIKit框架封装好的UIBezierPath对象来进行绘制图形

- (void)drawRect:(CGRect)rect {

// 1.获取图形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

// 2.创建路径对象

UIBezierPath*path = [UIBezierPathbezierPathWithRect:CGRectMake(50,50,100,100)];

// 3.把路径添加到上下文中

CGContextAddPath(ctx, path.CGPath);

// 4.渲染

CGContextStrokePath(ctx);

}

```

//其它演练–核心代码




//绘制圆角矩形框

UIBezierPath*path =

[UIBezierPathbezierPathWithRoundedRect:CGRectMake(50,50,150,150)cornerRadius:20];//如果这里的圆角半径写成宽度高度的一半,那么就是一个圆

//绘制一个圆形

UIBezierPath*path =

[UIBezierPathbezierPathWithOvalInRect:CGRectMake(50,50,150,150)];

//绘制扇形

1> center :圆心

2> redius :半径

3> startAngle :起始角度

4> endAngle :结束角度

5> clockwise : YES ->顺时针旋转NO ->逆时针旋转

UIBezierPath*path =

[UIBezierPathbezierPathWithArcCenter:CGPointMake(150,150)radius:100startAngle:0endAngle:M_PIclockwise:YES];

Even-Odd


展示效果

rule :奇偶填充规则

当一个点被覆盖过奇数次则“填充”,偶数次则“不填充”.

```

//代码实现

- (void)drawRect:(CGRect)rect {

// 1.获取图形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

// 2.绘制路径

UIBezierPath*path1 = [UIBezierPathbezierPathWithRect:CGRectMake(250,30,20,200)];

UIBezierPath*path2 = [UIBezierPathbezierPathWithArcCenter:CGPointMake(200,150)radius:80startAngle:0endAngle:M_PI*2clockwise:YES];

UIBezierPath*path3 = [UIBezierPathbezierPathWithRect:CGRectMake(100,100,200,100)];

// 3.添加路径

CGContextAddPath(ctx, path1.CGPath);

CGContextAddPath(ctx, path2.CGPath);

CGContextAddPath(ctx, path3.CGPath);

// 4.渲染

//说明:被覆盖过奇数次数的点填充,被覆盖过偶数次的点不填充

CGContextDrawPath(ctx,kCGPathEOFill);

}

```

nonzero

winding number rule :非零绕数规则


当一个点被从左到右覆盖过标记为1,从右到左覆盖过标记为-1,当标记为0的时候不填充,其它则填充.简单总结,这个规则与方向有关,与次数无关.

//代码实现

```

- (void)drawRect:(CGRect)rect

{

// 1.获取图形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

// 2.绘制路径

UIBezierPath*path1 = [UIBezierPathbezierPathWithArcCenter:CGPointMake(150,150)radius:100startAngle:0endAngle:M_PI*2clockwise:YES];

UIBezierPath*path2 = [UIBezierPathbezierPathWithArcCenter:CGPointMake(150,150)radius:50startAngle:0endAngle:M_PI*2clockwise:NO];

// 3.添加路径

CGContextAddPath(ctx,

path1.CGPath);

CGContextAddPath(ctx, path2.CGPath);

// 4.渲染

CGContextDrawPath(ctx,kCGPathFill);

}

```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 第一步:先科普一下基础知识: Core Graphics是基于C的API,可以用于一切绘图操作 Core Grap...
    真爱要有你才完美阅读 2,374评论 0 1
  • Quartz2D以及drawRect的重绘机制字数1487 阅读21 评论1 喜欢1一、什么是Quartz2D Q...
    PurpleWind阅读 730评论 0 3
  • 什么是Quartz2D 是一个二维的绘图引擎,同时支持iOS和Mac系统 Quartz2D的API是纯C语言的,它...
    Mario_ZJ阅读 549评论 0 1
  • 1每天一套一遍真题,过几天结合一千题大量刷题。 2把小本看完,每天坚持钻研真题与背单词。 3每天坚持背,大量背,默...
    最后几天阅读 85评论 0 0
  • 我们的每一次相遇都是一天又一天的缓慢告别。时间让爱我们的人和我们的爱人渐行渐远,而我们却无力去改变什么。 找核心 ...
    93650345d0d1阅读 131评论 0 0