什么是Quartz2D
1、Quartz 2D 是一个二维绘图引擎,同时支持iOS和Mac系统
2、Quartz 2D 能完成的工作:
-
绘制图形 : 线条三角形矩形圆弧等
-
绘制文字
-
绘制生成图片(图像)
-
读取生成PDF
-
截图裁剪图片
-
自定义UI控件
图形上下文
1、图形上下文(Graphics Context):是一个 CGContextRef 类型的数据
2、图形上下文的作用:
-
保存绘图信息、绘图状态
-
决定绘制的输出目标(绘制到什么地方去?)
相同的一套绘图序列,指定不同的 Graphics Context,就可将相同的图像绘制到不同的目标上
3、Quartz2D 提供了以下几种类型的 Graphics Context:
-
BitmapGraphics Context
-
PDFGraphics Context
-
WindowGraphics Context
-
LayerGraphics Context
-
PrinterGraphics Context
自定义view
1、如何利用 Quartz2D 绘制东西到 view 上?
-
首先,得有图形上下文,因为它能保存绘图信息,并且决定着绘制到什么地方去
-
其次,那个图形上下文必须跟view相关联,才能将内容绘制到view上面
2、自定义view的步骤
-
新建一个类,继承自 UIView
-
实现 - (void)drawRect:(CGRect)rect 方法,然后在这个方法中
-
取得跟当前view相关联的图形上下文
-
绘制相应的图形内容
-
利用图形上下文将绘制的所有内容渲染显示到view上面
3、为什么要在 drawRect 里面绘图
只有在这个方法里面才能获取到跟 View 的 layer 相关联的图形上下文
当这个View要显示的时候才会调用drawRect绘制图形
注意:rect是当前控件的bounds
画线
1、步骤:
-
获取图形上下文
-
描述路径
-
把路径添加到上下文
-
渲染上下文
2、直线
方式1:(最原始的绘图方式)
// 1.获取图形上下文 // 目前我们所用的上下文都是以UIGraphics // CGContextRef Ref:引用 CG:目前使用到的类型和函数 一般都是CG开头 CoreGraphics CGContextRef ctx = UIGraphicsGetCurrentContext(); // 2.描述路径 // 创建路径 CGMutablePathRef path = CGPathCreateMutable(); // 设置起点 // path:给哪个路径设置起点 CGPathMoveToPoint(path, NULL, 0, 250); // 添加一根线到某个点 CGPathAddLineToPoint(path, NULL, 250, 0); // 3.把路径添加到上下文 CGContextAddPath(ctx, path); // 4.渲染上下文 CGContextStrokePath(ctx);
方式2:(原生)
// 获取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 描述路径 // 设置起点 CGContextMoveToPoint(ctx, 0, 0); CGContextAddLineToPoint(ctx, 250, 250); // 渲染上下文 CGContextStrokePath(ctx);
方式3:贝瑟尔路径
// UIKit已经封装了一些绘图的功能 // 贝瑟尔路径 // 创建路径 UIBezierPath *path = [UIBezierPath bezierPath]; // 设置起点 [path moveToPoint:CGPointMake(0, 125)]; // 添加一根线到某个点 [path addLineToPoint:CGPointMake(250, 125)]; // 绘制路径 [path stroke];
3、线的相关操作
原生
// 获取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 描述路径 //起点 CGContextMoveToPoint(ctx, 50, 50); CGContextAddLineToPoint(ctx, 100, 50); // 设置起点 CGContextMoveToPoint(ctx, 80, 60); // 默认下一根线的起点就是上一根线终点 CGContextAddLineToPoint(ctx, 100, 200); // 设置绘图状态,一定要在渲染之前 // 颜色 [[UIColor redColor] setStroke]; // 线宽 CGContextSetLineWidth(ctx, 5); // 设置连接样式 CGContextSetLineJoin(ctx, kCGLineJoinBevel); // 设置顶角样式 CGContextSetLineCap(ctx, kCGLineCapRound); // 渲染上下文 CGContextStrokePath(ctx);
贝瑟尔路径
UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(50, 50)]; [path addLineToPoint:CGPointMake(200, 200)]; // 线宽 path.lineWidth = 10; // 颜色 [[UIColor redColor] set]; [path stroke]; UIBezierPath *path1 = [UIBezierPath bezierPath]; [path1 moveToPoint:CGPointMake(0, 0)]; [path1 addLineToPoint:CGPointMake(30, 60)]; [[UIColor greenColor] set]; path1.lineWidth = 3; [path1 stroke];
比较:
从代码中可以看出,原生的线操作只能将线绘制为一种样式,但是贝瑟尔路径的对线的操作可以根据路径的不同来绘制不同样式的线条
3、曲线
方式1(原生)
// 原生绘制方法 // 获取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 描述路径 // 设置起点 CGContextMoveToPoint(ctx, 150, 50); // CGContextAddQuadCurveToPoint(CGContextRef cg_nullable c, CGFloat cpx, CGFloat cpy, CGFloat x, CGFloat y) // cpx:控制点的x // cpy:控制点的y // x, y 为线结束的点的坐标 CGContextAddQuadCurveToPoint(ctx, 50, 50, 50, 150); // 渲染上下文 CGContextStrokePath(ctx);
方式2(贝瑟尔路径)
// 圆弧 // + (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise; // Center:圆心 // radius:半径 // startAngle:开始角度 // endAngle:结束角度 // clockwise:YES:顺时针 NO:逆时针 CGPoint center = CGPointMake(125, 125); UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES]; [path stroke];
4、扇形
未填充
// 扇形 CGPoint center = CGPointMake(125, 125); UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES]; // 添加一根线到圆心 [path addLineToPoint:center]; // 封闭路径,关闭路径:从路径的终点到起点 [path closePath]; [path stroke];
代码效果图:
填充
// 扇形 CGPoint center = CGPointMake(125, 125); UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES]; // 添加一根线到圆心 [path addLineToPoint:center]; // 填充:必须是一个完整的封闭路径,默认就会自动关闭路径 [path fill];
代码效果图:
5、圆角矩形
// 圆角矩形 // + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; // cornerRadius:圆角的弧度,当值为边长的一半时,画出来的图像为圆形 UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(20, 20, 200, 200) cornerRadius:50]; [path stroke]; // 填充:必须是一个完整的封闭路径,默认就会自动关闭路径 // [path fill];
代码效果图:
相关操作同贝塞尔路径的相关操作类似,大家可以试试,对以上内容有什么建议的可以直接联系我,O(∩_∩)O谢谢!