iOS程序猿之iOS绘图基础(draw)

iOS程序猿之iOS绘图基础(draw)

iOS绘图基础(draw)

先说几个基本概念:

context:上下文,ios绘图的方法都需要传一个上下文context,这个context在重写uiview的drawRect的方法里调用UIGraphicsGetCurrentContext()获取

path:路径,ios绘图可以想象为你拿着一支笔去画图,画几条线或几个点从而形成一个路径,之后可以利用理解去填色或者描边

stroke,fill 描边和填充,每个路径都需要填充或者描边后才能在视图中看见,他们都各自有很多样式可以设置,常见的有颜色、粗细、渐变,连接样式等等。

画图可以使用默认路径画,或者单独创建path画图,对应画图的api并不完全相同,是两组名称相似的api,两组pi常用的方法如下

CGContextMoveToPoint设置起点

CGContextClosePath 连接起点和当前点

CGPathCreateMutable 类似于 CGContextBeginPath

CGPathMoveToPoint 类似于 CGContextMoveToPoint

CGPathAddLineToPoint 类似于 CGContextAddLineToPoint

CGPathAddCurveToPoint 类似于 CGContextAddCurveToPoint

CGPathAddEllipseInRect 类似于 CGContextAddEllipseInRect

CGPathAddArc 类似于 CGContextAddArc

CGPathAddRect 类似于 CGContextAddRect

CGPathCloseSubpath 类似于 CGContextClosePath

CGContextAddPath函数把一个路径添加到graphics

画图步骤

1:获取context,

2:设置路径

CGContextStrokePath(ctx); //描出路径

CGContextFillPath(ctx) 使用非零绕数规则填充当前路径

CGContextDrawPath 两个参数决定填充规则,kCGPathFill表示用非零绕数规则,kCGPathEOFill表示用奇偶规则,kCGPathFillStroke表示填充,kCGPathEOFillStroke表示描线,不是填充

CGContextEOFillPath 使用奇偶规则填充当前路径

CGContextFillRect 填充指定的矩形

CGContextFillRects 填充指定的一些矩形

CGContextFillEllipseInRect 填充指定矩形中的椭圆

3:填充或描边路径

关于填充颜色 填充颜色有3种模式,分别是1:填充笔触,就是只给路径描边,2:根据路径填充颜色 3:填充笔触和颜色。填充颜色也分为非零绕数规则和奇偶规则,这个概念比较复杂难以解释,大家可以百度看看或者花几个图试试就明白。

几种基础绘图的代码

1.准备工作

新建一个继承于UIView的类, 重写-(void)drawRect:(CGRect)rect; 方法

// 重写drawRect

- (void)drawRect:(CGRect)rect

{

[super drawRect:rect];

// 1.获取上下文

CGContextRef contextRef = UIGraphicsGetCurrentContext();

/**********2.设置画图相关样式参数*********/

// 设置笔触的颜色

CGContextSetStrokeColorWithColor(contextRef, [UIColor blueColor].CGColor); // 设置颜色有很多方法,推荐这个

// 设置笔触的宽度

CGContextSetLineWidth(contextRef, 2);

// 设置填充色

CGContextSetFillColorWithColor(contextRef, [UIColor purpleColor].CGColor);

// 设置拐点样式

/**

* enum CGLineJoin {

* kCGLineJoinMiter, //尖的,斜接

* kCGLineJoinRound, //圆

* kCGLineJoinBevel //斜面

* }

*/

CGContextSetLineJoin(contextRef, kCGLineJoinRound);

// 设置线两端的样式

/**

* enum CGLineCap {

* kCGLineCapButt,

* kCGLineCapRound,

* kCGLineCapSquare

* };

*/

CGContextSetLineCap(contextRef, kCGLineCapRound);

// 设置虚线线条的样式

// CGFloat lengths[] = {10, 10};

// CGContextSetLineDash(contextRef, 0, lengths, 2);

/**********设置画图相关样式参数*********/

/**********3.开始画图*********/

// 画线

[self drawline:contextRef];

// 画圆,圆弧,贝塞尔曲线

[self drawCircle:contextRef];

// 画矩形,画椭圆,多边形

[self drawShape:contextRef];

// 画文字

[self drawText:contextRef];

// 画图片

[self drawPicture:contextRef];

/**********结束画图*********/

}

2.画线

第一个方法我写的比较详细,写了使用path的方式和直接画线的方式。推荐使用path的方式画线。 另外,第一个方法也写了移动笔触画线和用点集合画线。后面方法只会涉及其中一种,因为方法都比较类似。

- (void)drawline:(CGContextRef)contextRef

{

// 画一条简单的线

CGPoint points1[] = {CGPointMake(10, 30), CGPointMake(300, 30)};

CGContextAddLines(contextRef, points1, 2);

// 画线方法1, 使用CGContextAddLineToPoint添加点画线,需要先设置一个起始点

// 设置起始点

CGContextMoveToPoint(contextRef, 50, 50);

// 添加一个点

CGContextAddLineToPoint(contextRef, 100, 50);

// 在添加一个点,变成折现

CGContextAddLineToPoint(contextRef, 150, 100);

// 在添加一个点,再折一下

CGContextAddLineToPoint(contextRef, 280, 100);

// 画线方法2

// 构造线路的点数组

CGPoint points2[] = {CGPointMake(50, 120), CGPointMake(100, 150), CGPointMake(150, 120), CGPointMake(200, 150), CGPointMake(250, 120)};

CGContextAddLines(contextRef, points2, 5); // 最后一个参数为要绘制点的个数

// 画线方法3

// 利用路径去画一组点(推荐使用路径的方式,虽然多了几行代码,带上逻辑更加清晰了)

// 路径1

CGMutablePathRef path1 = CGPathCreateMutable();

CGPathMoveToPoint(path1, &CGAffineTransformIdentity, 30, 180); // 起始点, CGAffineTransformIdentity 类似于初始化一些参数

CGPathAddLineToPoint(path1, &CGAffineTransformIdentity, 30, 220); // 添加一个点

CGPathAddLineToPoint(path1, &CGAffineTransformIdentity, 80, 220); // 添加一个点

// 将路径1加入contextRef

CGContextAddPath(contextRef, path1);

// path同样有方法CGPathAddLines()添加一组路径,和CGContextAddLines()差不多

/******** 上面的方法都要写下面这两句代码 ********/

// 描出笔触

CGContextStrokePath(contextRef);

// 填充

CGContextFillPath(contextRef);

}

3. 画圆,圆弧,贝塞尔曲线

画圆和圆弧是一回事,只是起点和重点位置不同,画圆画弧线主要依赖于这几个方法CGContextAddArc,CGContextAddArcToPoint,CGContextAddCurveToPoint,CGContextAddQuadCurveToPoint后面两个方法是贝塞尔二次曲线和三次曲线

- (void)drawCircle:(CGContextRef)contextRef

{

// 画笔改成紫色,便于区别

CGContextSetStrokeColorWithColor(contextRef, [UIColor greenColor].CGColor);

/** 绘制路径 方法一

* void CGContextAddArc (

* CGContextRef c,

* CGFloat x, //圆心的x坐标

* CGFloat y, //圆心的x坐标

* CGFloat radius, //圆的半径

* CGFloat startAngle, //开始弧度

* CGFloat endAngle, //结束弧度

* int clockwise //0表示顺时针,1表示逆时针

* );

*/

// 圆

CGContextAddArc(contextRef, 100, 100, 50, 0, M_PI*2, 0);

CGContextStrokePath(contextRef);

// 半圆

CGContextAddArc(contextRef, 100, 200, 50, M_PI, M_PI*2, 0);

CGContextStrokePath(contextRef);

/**

* 绘制路径 方法二,这个方法适合绘制弧度,端点p1和p2是弧线的控制点,类似photoshop中的钢笔工具控制曲线,还不明白请去了解贝塞尔曲线

* void CGContextAddArcToPoint(

* CGContextRef c,

* CGFloat x1, //端点1的x坐标

* CGFloat y1, //端点1的y坐标

* CGFloat x2, //端点2的x坐标

* CGFloat y2, //端点2的y坐标

* CGFloat radius //半径

* )

*/

// 1/4 弧度*4 划出一个圆形

CGContextMoveToPoint(contextRef, 100, 100);

CGContextAddArcToPoint(contextRef, 100, 50, 150, 50, 50);

CGContextAddArcToPoint(contextRef, 200, 50, 200, 100, 50);

CGContextAddArcToPoint(contextRef, 200, 150, 150, 150, 50);

CGContextAddArcToPoint(contextRef, 100, 150, 100, 100, 50);

CGContextStrokePath(contextRef);

// 贝塞尔曲线

CGContextSetStrokeColorWithColor(contextRef, [UIColor orangeColor].CGColor); // 画笔颜色

/** 三次曲线函数

* void CGContextAddCurveToPoint (

* CGContextRef c,

* CGFloat cp1x, //控制点1 x坐标

* CGFloat cp1y, //控制点1 y坐标

* CGFloat cp2x, //控制点2 x坐标

* CGFloat cp2y, //控制点2 y坐标

* CGFloat x, //直线的终点 x坐标

* CGFloat y //直线的终点 y坐标

* );

*/

CGContextMoveToPoint(contextRef, 100, 300);

CGContextAddCurveToPoint(contextRef, 100, 300, 200, 0, 200, 300);

CGContextStrokePath(contextRef);

//三次曲线可以画圆弧

CGContextMoveToPoint(contextRef, 200, 200);

CGContextAddCurveToPoint(contextRef, 200, 100, 300, 100, 300 ,100);

CGContextStrokePath(contextRef);

/** 二次曲线

* void CGContextAddQuadCurveToPoint (

* CGContextRef c,

* CGFloat cpx, //控制点 x坐标

* CGFloat cpy, //控制点 y坐标

* CGFloat x, //直线的终点 x坐标

* CGFloat y //直线的终点 y坐标

* );

*/

CGContextMoveToPoint(contextRef, 100, 100);

CGContextAddQuadCurveToPoint(contextRef, 200, 0, 300, 150);

CGContextStrokePath(contextRef);

}

4.画矩形,画椭圆,多边形

- (void)drawShape:(CGContextRef)contextRef

{

CGContextSetFillColorWithColor(contextRef, [UIColor blackColor].CGColor);

// 画椭圆,如果长宽相等就是圆

CGContextAddEllipseInRect(contextRef, CGRectMake(50, 250, 50, 100));

// 画矩形,长宽相等就是正方形

CGContextAddRect(contextRef, CGRectMake(150, 250, 50, 100));

// 画多边形,多边形是通过path完成的

CGMutablePathRef path = CGPathCreateMutable();

CGPathMoveToPoint(path, &CGAffineTransformIdentity, 50, 350);

CGPathAddLineToPoint(path, &CGAffineTransformIdentity, 100, 350);

CGPathAddLineToPoint(path, &CGAffineTransformIdentity, 80, 400);

CGPathCloseSubpath(path);

CGContextAddPath(contextRef, path);

// 填充

CGContextFillPath(contextRef);

}

5. 画文字

- (void)drawText:(CGContextRef)contextRef

{

// 文字样式

UIFont *font = [UIFont systemFontOfSize:18];

NSDictionary *dict = @{NSFontAttributeName:font, NSForegroundColorAttributeName:[UIColor colorWithRed:0.167 green:0.752 blue:1.000 alpha:1.000]};

[@"荣耀归来" drawInRect:CGRectMake(100, 450, 100, 50) withAttributes:dict];

}

6.画图片

// 画图片

- (void)drawPicture:(CGContextRef)contextRef

{

UIImage *image = [UIImage imageNamed:@"17.png"];

[image drawInRect:CGRectMake(100, 500, 100, 150)]; // 在坐标系中画出图片

}

相关推荐

bst365大陆投注 王者荣耀:最克制诸葛亮的英雄,这三个英雄一选诸葛亮直接废了

王者荣耀:最克制诸葛亮的英雄,这三个英雄一选诸葛亮直接废了

365bet官网网址是多少 令人疯狂的无机生命:《死亡空间》里的“神印”考证

令人疯狂的无机生命:《死亡空间》里的“神印”考证

365bet官网网址是多少 龙潭战役孙传芳为何仍失败?失策在于

龙潭战役孙传芳为何仍失败?失策在于"四个没有"