Quartz 2D:
- Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac OS X系统(跨平台,纯C语言)。包含在Core Graphics框架中。
Quartz 2D能完成的工作:
- 绘制图形: 线条/三角形/矩形/圆/弧等
- 绘制文字
- 绘制/生成图片
- 读取/生成PDF
- 自定义UI控件
- ... ...
Quartz 2D绘图主要步骤:
-
通过Quartz 2D原生API绘图:
- 获取[图形上下文]对象
- 向[图形上下文]对象中添加[路劲]
- 渲染(把[图形上下文]中的图形绘制到对应的设备上)
图形上下文CGContextRef
- 图形上下文(Graphics Context): 是一个CGContextRef类型的数据
- 图形上下文中主要包含如下信息:
- 绘制路径(各种各样的图形)
- 绘图状态(颜色、线宽、样式、旋转、缩放、平移、图片剪裁区域等)
- 输出目标(绘制到什么地方去?UIView、PDF、打印机等)
图形上下文:
提供了以下几种图形上下文:
- Bitmap Graphics Context --效果画到图片上
- PDF Graphics Context --画到PDF上
- Window Graphics Context --画到Mac电脑窗口上
- Layer Graphics Context(UI 控件) --画到UI控件上
- Printer Graphics Context --画到打印机
PS: 相同的一套绘图序列,指定不同的Graphics Context, 就可以将相同的图像绘制到不同的目标上。
通过UIBezierPath + 图形上下文绘制图形:
- 获取图形上下文对象
- 创建UIBezierPath对象
- 向UIBezierPath对象中绘制图形
- 把UIBezierPath对象添加到上下文中
- 把上下文对象渲染到设备上
PS: UIBezierPath对象可以独立使用,无需手动获取 图形上下文 对象,这里为了更好的理解 图形上下文对象,采取手动获取图形上下文对象的方式来绘图。
自定义UIView时,实现文件中:
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
即:在drawRect:方法中才能取得跟view相关联的图形上下文 我们才能绘制各种图形。
drawRect: 方法仅在view第一次显示在Window上时调用一次,如果想重新调用 需要手动调用setNeedsDisplay或setNeedsDisplayInRect:方法。
不可手动调用drawRect: 方法,该方法是由系统在需要调用的时候调用--不能主动调用该方法。
-
Quartz 2D原生API绘制:
- 绘制直线:
//1.获取图形上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//2. 绘制各种路径
//2.1 设置一个起点
CGContextMoveToPoint(ref, 20, 100);
//2.2 设置一个终点
CGContextAddLineToPoint(ref, 100, 160);
//3. 渲染
CGContextStrokePath(ref);
- 绘制三角形:
//1.获取图形上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//2. 绘制各种路径
//2.1 设置一个起点
CGContextMoveToPoint(ref, 20, 100);
//2.2 设置一个终点
CGContextAddLineToPoint(ref, 100, 160);
//2.3 再添加一个终点
CGContextAddLineToPoint(ref, 150, 100);
//2.4 关闭路径
CGContextClosePath(ref);
//3. 渲染
CGContextStrokePath(ref);
-
UIBezierPath绘制图形:
- 绘制直线:
//1. 获取图形上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//2. 创建UIBezierPath对象
UIBezierPath *path = [UIBezierPath bezierPath];
//3. 向UIBezierPath添加路径
[path moveToPoint:CGPointMake(30, 100)];
[path addLineToPoint:CGPointMake(300, 300)];
//4. 把UIBezierPath对象添加到上下文中
CGContextAddPath(ref, path.CGPath);
//设置状态信息
//i. 线宽
CGContextSetLineWidth(ref, 10);
//ii. 设置线段两端样式
/*
typedef CF_ENUM(int32_t, CGLineCap) {
kCGLineCapButt, //默认
kCGLineCapRound,
kCGLineCapSquare
};
*/
CGContextSetLineCap(ref, kCGLineCapRound);
//iii. 设置线段连接处的样式
/*
typedef CF_ENUM(int32_t, CGLineJoin) {
kCGLineJoinMiter, //默认
kCGLineJoinRound,
kCGLineJoinBevel
};
*/
CGContextSetLineJoin(ref, kCGLineJoinRound);
//iV. 设置绘图颜色
// [[UIColor redColor] setStroke]; //画边的时候使用红色 --仅用于渲染时 为kCGPathStroke时
// [[UIColor yellowColor] setFill]; //设置填充时颜色 --kCGPathFill
[[UIColor blueColor] set]; //填充和描边 使用同一颜色
//5. 渲染
// CGContextStrokePath(ref);
//上面所有的设置状态的代码,都会将状态应用于当前上下文中的所有路径
// CGContextDrawPath(ref, kCGPathStroke); //与[[UIColor redColor] setStroke];对应
// CGContextDrawPath(ref, kCGPathFill); //与[[UIColor yellowColor] setFill];对应
CGContextDrawPath(ref, kCGPathFillStroke); //既填充也描边 //与[[UIColor blueColor] set];对应
- 绘制三角形:
//1. 获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//2. 创建UIBezierPath对象
UIBezierPath *path = [UIBezierPath bezierPath];
//3. 向UIBezierPath添加路径
[path moveToPoint:CGPointMake(100, 200)];
[path addLineToPoint:CGPointMake(160, 300)];
[path addLineToPoint:CGPointMake(220, 200)];
//关闭路径
[path closePath];
//4. 把UIBezierPath对象添加到上下文中
CGContextAddPath(ref, path.CGPath); //OC对象 转 C语言
//5. 渲染
// CGContextStrokePath(ref);
//or
/*
typedef CF_ENUM (int32_t, CGPathDrawingMode) {
kCGPathFill,
kCGPathEOFill,
kCGPathStroke,
kCGPathFillStroke,
kCGPathEOFillStroke
};
*/
CGContextDrawPath(ref, kCGPathStroke);
- 绘制矩形:
//获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//创建UIBezierPath
//向UIBezierPath中添加路径
//绘制矩形
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 200, 100)];
//把UIBezierPath添加到上下文中
CGContextAddPath(ref, path.CGPath);
//渲染
/*
typedef CF_ENUM (int32_t, CGPathDrawingMode) {
kCGPathFill,
kCGPathEOFill,
kCGPathStroke,
kCGPathFillStroke,
kCGPathEOFillStroke
};
*/
CGContextDrawPath(ref, kCGPathStroke);
// CGContextDrawPath(ref, kCGPathFill); //填充
- 绘制椭圆:
//获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//创建UIBezierPath
//向UIBezierPath中添加路径
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 200, 100)];
//把UIBezierPath添加到上下文中
CGContextAddPath(ref, path.CGPath);
//渲染
/*
typedef CF_ENUM (int32_t, CGPathDrawingMode) {
kCGPathFill,
kCGPathEOFill,
kCGPathStroke,
kCGPathFillStroke,
kCGPathEOFillStroke
};
*/
CGContextDrawPath(ref, kCGPathStroke);
// CGContextDrawPath(ref, kCGPathFill); //填充
-
绘制圆形:
- 第一种方式: 画椭圆方法 --宽高相等
//获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//创建UIBezierPath
//向UIBezierPath中添加路径
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 100, 100)];
//把UIBezierPath添加到上下文中
CGContextAddPath(ref, path.CGPath);
//渲染
/*
typedef CF_ENUM (int32_t, CGPathDrawingMode) {
kCGPathFill,
kCGPathEOFill,
kCGPathStroke,
kCGPathFillStroke,
kCGPathEOFillStroke
};
*/
CGContextDrawPath(ref, kCGPathStroke);
// CGContextDrawPath(ref, kCGPathFill); //填充
- 第二种方式: 绘制矩形 --宽高相等 cornerRadius: 边长/2.0
//获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//创建UIBezierPath
//向UIBezierPath中添加路径
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 100, 100) cornerRadius:50];
//把UIBezierPath添加到上下文中
CGContextAddPath(ref, path.CGPath);
//渲染
/*
typedef CF_ENUM (int32_t, CGPathDrawingMode) {
kCGPathFill,
kCGPathEOFill,
kCGPathStroke,
kCGPathFillStroke,
kCGPathEOFillStroke
};
*/
CGContextDrawPath(ref, kCGPathStroke);
// CGContextDrawPath(ref, kCGPathFill); //填充
- 第三种方式: 绘制圆弧方式画一个圆
//获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//创建UIBezierPath
//向UIBezierPath中添加路径
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:50 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
//把UIBezierPath添加到上下文中
CGContextAddPath(ref, path.CGPath);
//渲染
/*
typedef CF_ENUM (int32_t, CGPathDrawingMode) {
kCGPathFill,
kCGPathEOFill,
kCGPathStroke,
kCGPathFillStroke,
kCGPathEOFillStroke
};
*/
CGContextDrawPath(ref, kCGPathStroke);
// CGContextDrawPath(ref, kCGPathFill); //填充
- 绘制圆弧:
//获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//创建UIBezierPath
//向UIBezierPath中添加路径
//画弧
//ArcCenter: 圆心
//radius: 半径
//startAngle: 开始弧度 --1弧度 = 180度
//endAngle: 结束弧度
//绘制一个弧 clockwise: 顺时针或逆时针
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:50 startAngle:0 endAngle:M_PI_2 clockwise:NO];
//把UIBezierPath添加到上下文中
CGContextAddPath(ref, path.CGPath);
//渲染
/*
typedef CF_ENUM (int32_t, CGPathDrawingMode) {
kCGPathFill,
kCGPathEOFill,
kCGPathStroke,
kCGPathFillStroke,
kCGPathEOFillStroke
};
*/
CGContextDrawPath(ref, kCGPathStroke);
// CGContextDrawPath(ref, kCGPathFill); //填充
- 绘制圆环:
//获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//创建UIBezierPath
//向UIBezierPath中添加路径
//画圆环
//直接画一个圆 设置线宽 --推荐使用这种方式
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:50 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
CGContextSetLineWidth(ref, 20); //线宽 里外各一半
//把UIBezierPath添加到上下文中
CGContextAddPath(ref, path.CGPath);
//渲染
/*
typedef CF_ENUM (int32_t, CGPathDrawingMode) {
kCGPathFill,
kCGPathEOFill,
kCGPathStroke,
kCGPathFillStroke,
kCGPathEOFillStroke
};
*/
CGContextDrawPath(ref, kCGPathStroke);
// CGContextDrawPath(ref, kCGPathFill); //填充
参考资料:
传智播客教程
iOS-Quartz2D
网友评论