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 ...
随机推荐
- Android 关于Acitivity 的setFlag以及launchmode的总结
Intent几种常见的flags: .FLAG_ACTIVITY_NEW_TASK:当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Acti ...
- 【Quartus警告】created implicit net for XXX.
[警告内容]Warning (10236): Verilog HDL Implicit Net warning at forward_replace.v(16): created implicit n ...
- 微软高性能缓存AppFabric (一) 安装
博客原文链接:http://www.cnblogs.com/Qbit/p/6088703.html AppFabric 缓存功能的前身是VeloCity ,它是基于windows平台的一个高速内存缓存 ...
- JS中的toString()和valueOf()方法
1.toString()方法:主要用于Array.Boolean.Date.Error.Function.Number等对象转化为字符串形式.日期类的toString()方法返回一个可读的日期和字符串 ...
- POJ-2195 Going Home---KM算法求最小权值匹配(存负边)
题目链接: https://vjudge.net/problem/POJ-2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致.man每移动一格 ...
- 【BZOJ3460】Jc的宿舍(树上莫队+树状数组)
点此看题面 大致题意: 一棵树,每个节点有一个人,他打水需要\(T_i\)的时间,每次询问两点之间所有人去打水的最小等待时间. 伪·强制在线 这题看似强制在线,但实际上,\(pre\ mod\ 2\) ...
- CXF学习记录
1 apache CXF入门 1.1 下载 官网:cxf.apache.org 下载CXF的开发包: Apache CXF = Celtix + Xfire 支持多种协议: SOAP1.1,1.2 X ...
- Java之JDK的下载与安装,java环境变量的配置,Editplus的下载与使用
JRE(Java Runtime Environment Java运行环境) 包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,如果想要运行一个开发 ...
- React后台管理系统-table-list组件
table-list组件可用于商品列表,用户列表页面 需要传入一个tableHeads集合和tablebody import React from 'react'; // 通用的列表 class ...
- iOS 中push和pop到底系统做了些什么事
iOS中的push和pop是一个很常用的视图切换方法,他们是成对出现的, 简而言之,push就是压栈,pop就是出栈! [self.navigationController pushViewContr ...