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,打印机等).


iOS_Quartz2D_ 基础_第1张图片


iOS_Quartz2D_ 基础_第2张图片



使用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简单演练

展示效果:


iOS_Quartz2D_ 基础_第3张图片


iOS_Quartz2D_ 基础_第4张图片


iOS_Quartz2D_ 基础_第5张图片

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

第一步,在控制器的界面中拖入一个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);

}

```

//其它演练–核心代码


iOS_Quartz2D_ 基础_第6张图片


iOS_Quartz2D_ 基础_第7张图片


iOS_Quartz2D_ 基础_第8张图片

//绘制圆角矩形框

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


iOS_Quartz2D_ 基础_第9张图片
展示效果

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 :非零绕数规则


iOS_Quartz2D_ 基础_第10张图片

当一个点被从左到右覆盖过标记为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);

}

```

你可能感兴趣的:(iOS_Quartz2D_ 基础)