iOS笔记052- Quartz2D-绘图
简介
Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统
Quartz 2D能完成的工作
绘制图形 : 线条\三角形\矩形\圆\弧等
绘制文字
绘制\生成图片(图像)
读取\生成PDF
截图\裁剪图片
自定义UI控件
使用Quartz 2D绘制图形需要绘制在UIView上,而且要自定义的view。
自定义view的步骤
1、新建一个类,继承自UIView
2、实现- (void)drawRect:(CGRect)rect方法,然后在这个方法中
3、取得跟当前view相关联的图形上下文
4、绘制相应的图形内容
5、利用图形上下文将绘制的所有内容渲染显示到view上面
几种简单的绘图方式
#pragma mark - 最原始的绘图方式1
- (void)draw2 {
// Drawing code
//获得图形上下文
CGContextRef con = UIGraphicsGetCurrentContext();
// 创建路径
CGMutablePathRef path = CGPathCreateMutable();
// 绘制一条线
// CGPathMoveToPoint(path, NULL, 50, 50);
// CGPathAddLineToPoint(path, NULL, 200, 200);
// 绘制矩形
// CGPathAddRect(path, NULL, CGRectMake(60, 60, 100, 100));
// CGPathAddEllipseInRect(path, NULL, CGRectMake(60, 60, 100, 100));
// 圆角矩形
// CGPathAddRoundedRect(path, NULL, CGRectMake(60, 60, 100, 100), 5, 5);
// 弧线
CGPathAddArc(path, NULL, 100, 100,30, 0, M_PI, YES);
// 添加路径到上下文中
CGContextAddPath(con, path);
// 显示到view中
CGContextStrokePath(con);
}
绘图方式2
#pragma mark - 绘图方式2
- (void)draw1 {
// Drawing code
//获得图形上下文
CGContextRef con = UIGraphicsGetCurrentContext();
// 绘制路径
// 绘制直线
// CGContextMoveToPoint(con, 0, 0);
// CGContextAddLineToPoint(con, 100, 100);
// CGContextAddLineToPoint(con, 50, 100);
//CGContextMoveToPoint(con, 50, 50);
//
// 绘制圆
// CGContextAddEllipseInRect(con, CGRectMake(60, 60, 100, 100));
// 绘制椭圆
// CGContextAddEllipseInRect(con, CGRectMake(60, 60, 150, 100));
// 绘制矩形
// CGContextAddRect(con, CGRectMake(60, 60, 150, 100));
// 绘制
CGContextAddArc(con, 0, 0, 50, M_PI, M_PI_2, YES);
// 显示到view中
CGContextStrokePath(con);
绘图方式3
#pragma mark - 绘图方式3-贝瑟尔路径绘图
// 贝瑟尔路径绘图
- (void)draw3 {
// Drawing code
// UIKit已经封装了一些绘图的功能
// 贝瑟尔路径
UIBezierPath *path = [UIBezierPathbezierPath];
// 绘制路径
// [path moveToPoint:CGPointMake(100, 100)];
// [path addLineToPoint:CGPointMake(200, 200)];
// 圆弧
[path addArcWithCenter:CGPointMake(100, 100) radius:50startAngle:0endAngle:M_PIclockwise:YES];// 顺时针绘制一个弧线
[path addLineToPoint:CGPointMake(100, 100)];
[[UIColorredColor] setStroke]; // 设置线条颜色
//
path.lineJoinStyle = kCGLineJoinRound; //
path.lineWidth = 2; // 宽度
path.lineCapStyle = kCGLineCapRound; // 样式
[path fill];
// 显示
[path stroke];
}
绘图状态的设置
#pragma mark - 设置线条状态在渲染之前
- (void)draw4 {
// Drawing code
// 获得图形上下文
CGContextRef ct = UIGraphicsGetCurrentContext();
// 绘制路径
CGContextMoveToPoint(ct, 100, 100);
CGContextAddLineToPoint(ct, 200, 200);
CGContextAddLineToPoint(ct, 100, 300);
// 设置绘图状态,一定要在渲染之前设置,并且一经设置,状态会一直持续下去,除非再次改变。
CGContextSetLineWidth(ct, 5);
[[UIColorredColor] setStroke];
CGContextSetLineJoin(ct, kCGLineJoinRound);
CGContextSetLineCap(ct, kCGLineCapRound);
// 渲染
CGContextStrokePath(ct);
}
绘制包含多个状态的图形
- (void)drawRect:(CGRect)rect {
// Drawing code
// 绘制多个状态不同的线
// 获得图形上下文
UIBezierPath *path = [UIBezierPath bezierPath];
// 绘制路径
[path moveToPoint:CGPointMake(100, 100)];
[path addLineToPoint:CGPointMake(200, 200)];
// 设置绘图状态,一定要在渲染之前设置,并且一经设置,状态会一直持续下去,除非再次改变。
[[UIColor redColor] setStroke];
// 渲染
[path stroke];
// 获得图形上下文
UIBezierPath *path1 = [UIBezierPath bezierPath];
// 绘制路径
[path1 moveToPoint:CGPointMake(200 , 200)];
[path1 addLineToPoint:CGPointMake(100, 150)];
// 设置绘图状态,一定要在渲染之前设置,并且一经设置,状态会一直持续下去,除非再次改变。
[[UIColor blueColor] setStroke];
// 渲染
[path1 stroke];
}
绘制饼状图
首先花圆弧,然后连接圆心,最后填充位一个扇形
// 饼状图2
- (void)drawRect:(CGRect)rect{
NSArray *arr = [self randomArray]; // 随机地返回一个数组,数组元素和为100
// 获取半径和圆心
CGFloat radius = self.frame.size.height/2 - 2;
CGPoint center = CGPointMake(radius, radius);
// 绘制角度
CGFloat startAngle = 0;
CGFloat endAngle = 0;
// 绘制图形
for (int i = 0 ; i < arr.count; i ++) {
// 计算角度
endAngle = startAngle + [arr[i] floatValue] / 100.0 * M_PI * 2;
// 绘制图形
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
[path addLineToPoint:center];
startAngle = endAngle;
// 设置颜色
[[self randomColor] set];
// 填充,并且把终点和起始点连接起来
[path fill];
}
}
随机返回数组,且元素和为100
// 返回随机数组,且数组元素和为100
- (NSArray *)randomArray
{
NSMutableArray *arr = [NSMutableArrayarray];
int total = 100;
int temp = 0;
for (int i = 0 ; i < arc4random_uniform(10) + 1;i ++) {
// 100 1~100
temp = arc4random_uniform(total) + 1;
// 随机出来的临时值等于总值,直接退出循环,因为已经把总数分配完毕,没必要在分配。
[arr addObject:@(temp)];
// 解决方式:当随机出来的数等于总数直接退出循环。
if (temp == total) {
break;
}
total -= temp;
}
// 如果总数大于0就添加到数组中
if (total ) {
[arr addObject:@(total)];
}
return arr;
}
返回随机颜色
// 返回随机的颜色
- (UIColor *)randomColor
{
// iOS:RGB返回是0~1
CGFloat r = arc4random_uniform(256) / 255.0;
CGFloat g = arc4random_uniform(256) / 255.0;
CGFloat b = arc4random_uniform(256) / 255.0;
return [UIColorcolorWithRed:r green:g blue:b alpha:1];
}
绘制柱状图
计算方柱个数,平分宽度,高度按占视图比例计算。
// 柱状图
- (void)drawRect:(CGRect)rect {
// 随机地返回一个数组,数组元素和为100
NSArray *arr = [self randomArray];
// 起始点和高度
CGFloat x = 0;
CGFloat y = 0;
CGFloat w = 0;
CGFloat h = 0;
NSInteger count = arr.count;
// 宽度
w = rect.size.width / (2*count - 1);
for (int i = 0 ; i < arr.count; i ++) {
// x坐标
x = 2*i * w;
// 高度
h = [arr[i] floatValue] / 100.0 * rect.size.height;
// y坐标
y = rect.size.height - h;
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(x, y, w, h)];
[[self randomColor] set];
[path fill];
}
}
文本显示
// 文本显示
- (void)drawRect:(CGRect)rect
{
NSString *str = @"哈尽快回家的客户发动机可舒服哈的尽快发货阿红的健康法哈德减肥哈第三方阿姐回复就爱的客户房间卡地方哈就等哈接电话发掘";
// 这个方法不会自动换行
// [str drawAtPoint:CGPointZero withAttributes:nil];
// 自动换行
[str drawInRect:rect withAttributes:nil];
}
富文本显示

// 富文本:带有状态的文本
- (void)drawRect:(CGRect)rect
{
NSString *str = @"哈尽快回家的客户发动机可舒服哈的尽快发货阿红的健康法哈德减肥哈第三方阿姐回复就爱的客户房间卡地方哈就等哈接电话发掘";
NSMutableDictionary *dict = [NSMutableDictionarydictionary];
// 属性的设置可以在UIkit框架的头文件里找到解释
// 字体颜色
dict[NSForegroundColorAttributeName] = [UIColorredColor];
// 字体大小
dict[NSFontAttributeName] = [UIFontsystemFontOfSize:30];
// 字体粗细
dict[NSStrokeWidthAttributeName] = @5;
// 颜色
dict[NSStrokeColorAttributeName] = [UIColorgreenColor];
// 阴影
NSShadow *sha = [[NSShadow alloc] init];
sha.shadowOffset = CGSizeMake(5, 5);
sha.shadowBlurRadius = 10;
sha.shadowColor = [UIColor yellowColor];
dict[NSShadowAttributeName] = sha;
// 绘制到视图
[str drawInRect:rect withAttributes:dict];
}
绘制图片到视图
drawAtPoint
drawInRect

drawAsPatternInrect
裁剪

// 绘制图形
- (void)drawRect:(CGRect)rect
{
// 超出裁剪区域的内容全部裁剪掉
// 注意:裁剪必须放在绘制之前
// UIRectClip(CGRectMake(0, 0, 100, 100));
UIImage *image = [UIImage imageNamed:@"010"];
// 默认按照图片比例显示
// [image drawAtPoint:CGPointZero];
// 将整个图片显示到rect中,拉伸或者缩小
[image drawInRect:rect];
// 默认填充显示
// [image drawAsPatternInRect:rect];
}
图形上下文状态
保存某个状态到栈顶,用于之后恢复。
// 图形上下文3 UIBezierPath:使用[path stroke];时上下文状态有UIBezierPath自身决定
- (void)drawRect:(CGRect)rect
{
//保存上下文状态,如果使用这种方法保存上下文状态的话,需要设置以CGContext开头的那些函数设置状态,
// 获取图形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 绘制第一条线
// 贝塞尔路线
UIBezierPath *path = [UIBezierPathbezierPath];
// 绘制路径
[path moveToPoint:CGPointMake(55, 55)];
[path addLineToPoint:CGPointMake(99, 90)];
// 添加路径到上下文
//将c路径转换成oc对象:CGPath
CGContextAddPath(ctx, path.CGPath);
// 保存上下文状态
CGContextSaveGState(ctx);
CGContextSetLineWidth(ctx, 5);
[[UIColorredColor] setStroke];
// 渲染上下文
// [path stroke];
CGContextStrokePath(ctx);
// 绘制第二条线
path = [UIBezierPath bezierPath];
// 绘制路径
[path moveToPoint:CGPointMake(100, 10)];
[path addLineToPoint:CGPointMake(100, 80)];
// 恢复上下文状态
CGContextRestoreGState(ctx);
// 添加路径到上下文
CGContextAddPath(ctx, path.CGPath);
// [[UIColor blueColor] setStroke];
// 渲染
// [path stroke];
CGContextStrokePath(ctx);
}
绘图刷新-定时器
如果在绘图的时候需要用到定时器,通常CADisplayLink
NSTimer很少用于绘图,因为调度优先级比较低,并不会准时调用
// 如果在绘图的时候需要用到定时器,通常CADisplayLink
// NSTimer很少用于绘图,因为调度优先级比较低,并不会准时调用
- (void)awakeFromNib
{
// 添加计时器,改变_smailY的值
// 比起NSTimer,CADisplayLink可以确保系统渲染每一帧的时候我们的方法都被调用,从而保证了动画的流畅性。
// CADisplayLink:每次屏幕刷新的时候就会调用,屏幕一般一秒刷新60次
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(timeChange)];
// 添加至运行主循环
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)timeChange
{
// 注意:这个方法并不会马上调用drawRect,其实这个方法只是给当前控件添加刷新的标记,等下一次屏幕刷新的时候才会调用drawRect
[self setNeedsDisplay];
}
矩阵操作
// 上下文矩阵操作
// 注意:矩阵操作必须要在添加路径之前
-(void)drawRect:(CGRect)rect
{
// 获取图形山下文
CGContextRef ctx1 = UIGraphicsGetCurrentContext();
// CGContextSaveGState(ctx1);
// 绘制路径1
// CGContextMoveToPoint(ctx1, 50, 50);
CGContextTranslateCTM(ctx1, 100, 0); // 添加路径之前进行矩阵操作
CGContextScaleCTM(ctx1, 2, 2);
CGContextRotateCTM(ctx1, M_PI_2);
CGContextAddEllipseInRect(ctx1, CGRectMake(10, 10, 50, 90));
[[UIColorredColor] setStroke];
CGContextSetLineWidth(ctx1, 5);
CGContextSetLineJoin(ctx1, kCGLineJoinRound);
// 渲染路径
CGContextStrokePath(ctx1);
}
iOS笔记052- Quartz2D-绘图的更多相关文章
- iOS:quartz2D绘图
Quartz-2D:绘图 一.介绍: •Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境 •Quartz 2D API可以实现许多功能,如基于路径的绘图.透明度.阴影 ...
- iOS开发之Quartz2D详解
1. 什么是Quartz2D? Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片( ...
- iOS开发之Quartz2D
1. Quartz2D概述及作用 Quartz2D的API是纯C语言的,Quartz2D的API来自于Core Graphics框架. 数据类型和函数基本都以CG作为前缀,比如: CG ...
- 阶段性总结⓵触摸事件&手势识别⓶Quartz2D绘图⓷CALayer图层⓸CAAnimation⓹UIDynamic UI动力学⓺KVC&KVO
知识点复习 1. 触摸事件&手势识别 1> 4个触摸事件,针对视图的 2> 6个手势识别(除了用代码添加,也可以用Storyboard添加) 附加在某一个特定视图上的, ...
- WPF笔记(1.10 绘图)——Hello,WPF!
原文:WPF笔记(1.10 绘图)--Hello,WPF! 书中的代码语法过时了,改写为以下(测试通过): <Button> <Button.L ...
- iOS基础 - Quartz 2D绘图的基本步骤
一.使用Quartz 2D绘图的基本步骤 1) 获取上下文context(绘制图形的地方) 2) 设置路径(路径是用来描述形状的) 3) 将路径添加到上下文 4) 设置上下文属性(设置颜色,线宽, ...
- matlab学习笔记9 高级绘图命令_2 图形的高级控制_视点控制和图形旋转_色图和颜色映像_光照和着色
一起来学matlab-matlab学习笔记9 高级绘图命令_2 图形的高级控制_视点控制和图形旋转_色图和颜色映像_光照和着色 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 < ...
- matlab学习笔记9 高级绘图命令_1 图形对象_根对象,轴对象,用户控制对象,用户菜单对象
一起来学matlab-matlab学习笔记9 高级绘图命令_1 图形对象_根对象,轴对象,用户控制对象,用户菜单对象 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matl ...
- matlab学习笔记8 基本绘图命令-三维绘图
一起来学matlab-matlab学习笔记8 基本绘图命令_6 三维绘图 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用>张德丰等著 ...
- matlab学习笔记8 基本绘图命令-初级二维绘图/交互式绘图
一起来学matlab-matlab学习笔记8 基本绘图命令_5 初级二维绘图/交互式绘图 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用&g ...
随机推荐
- 360 so动态脱壳
环境及工具 手机 : 中兴 U887 系统版本: Android 2.3.5 工具 : IDA pro 6.6 .0101Editor 版权声明:未经许可,随便转载 目前so加壳有 ...
- iOS开发 - 在状态栏显示FPS,CPU和内存信息
原理 FPS的计算 CoreAnimation有一个很好用的类CADisplayLink,这个类会在每一帧绘制之前调用,并且可以获取时间戳.于是,我们只要统计出,在1s内的帧数即可. - (void) ...
- System Center Configuration Manager 2016 必要条件准备篇(Part1)
步骤4.创建系统管理容器 SCCM 2016 配置管理系列(Part 1- 4) 介绍AD01上配置了Active Directory域服务(ADDS),然后将Configuration Manag ...
- HDU 1305 Immediate Decodability 可直接解码吗?
题意:一个码如果是另一个码的前缀,则 is not immediately decodable,不可直接解码,也就是给一串二进制数字给你,你不能对其解码,因解码出来可能有多种情况. 思路:将每个码按长 ...
- [Git] Create a new repository on the command line
echo "# xxx" >> README.md git init git add README.md git commit -m "first commi ...
- POJ1061 青蛙的约会 __一维世界的爱情
由于今天上午在做数论知识的笔记,发现那时候赵老师讲的线性丢番图(求ax+by=c的特解)部分完全搞不懂,后来网上查了一下才发现这个公式就是求同余方程,所用方法就是扩展欧几里得算法.正好红皮书上有这么一 ...
- pta 编程题15 列出连通集
其它pta数据结构编程题请参见:pta 题目 题目要求分别以深度优先搜索和广度优先搜索输出图的连通集. 广度优先搜索要用到队列,先回顾一下循环队列: struct QNode { int* Data; ...
- Kibana功能一览
Overview标签 总共32个请求,最大响应时间:4.7秒 Usage标签 可以看到HTTP请求的发起时间分布 Performance and Quality 6个请求里,响应时间在100毫秒以下的 ...
- find - 递归地在层次目录中处理文件
总览 SYNOPSIS find [path...] [expression] 描述 DESCRIPTION 这个文档是GNU版本 find 命令的使用手册. find 搜索目录树上的每一个文件名,它 ...
- 问题006:为什么用java.exe执行编译的类文件的时候,不这样写java Welcome.class
为什么用java.exe执行编译的类文件的时候,不这样写java Welcome.class 是因为java虚拟机调用Welcome的时候,已经替我们增减了.class,如果你还要写java Welc ...