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 ...
随机推荐
- uLua学习之使用协程(终)
前言 今天是本系列的第六篇文章,也是最后一篇,我们来看看uLua中如何来实现协程吧.首先,让我们明确协程的概念.在百度百科上的是这样说的,协程更适合于用来实现彼此熟悉的程序组件,如合作式多任务,迭代器 ...
- 约瑟夫环问题及PHP代码实现
php实现猴子选大王 <?php /** * @param $n 猴子数量 * @param $m 出列的那个数 */ function king($n,$m){ $monkeys = rang ...
- wu2198:难得的波段抄底机会
很好的波段抄底机会 个人浅见看,目前染料股跌出的机会明显,养殖股波段机会明显,芯片.半导体.集成电路.北导.软件.国产操作系统等科技股短线机会不错.另外,大盘指数2856/2806区域的波段操作机会不 ...
- 生成.m文件的python代码中出现的错误
错误代码 import tempfile import subprocess import shlex import os import numpy as np import scipy.io scr ...
- ReentrantReadWriteLock的使用
ReentrantReadWriteLock的规则是: 多线程情况下:读-写互斥.写-读互斥.写-写互斥.读-读共享 验证“读-写互斥.写-读互斥.写-写互斥.读-读共享” //单个线程 读-读 不互 ...
- 通过cmd查看环境变量名对应的环境变量值
在VS环境中通常要添加路径,不过基本都是按照往上提供的方法添加变量名形如:$(VC_IncludePath),但是如何通过cmd命令找到真正的路径呢 未完待续……
- Hadoop集群批量命令执行
./pdsh -R ssh -w node-10-0[0-5] hostname -R:指定传输方式,默认为rsh,本例为ssh,如果希望ssh传输需要另行安装pdsh-rcmd-ssh,如果希望ss ...
- Uva 网络(Network,Seoul 2007,LA 3902)
#include<iostream> #include<cstring> #include<vector> using namespace std; +; int ...
- 【计数】cf938E. Max History
发现有一种奇怪的方法不能快速预处理? 复习一下常见的凑组合数的套路 You are given an array a of length n. We define fa the following w ...
- C/C++程序基础 (六)面向对象
类的特性 抽象.封装.继承.多态.重载 class 和 struct 区别 C中struct仅仅可以包含数据成员,不可以有成员函数,属于复杂数据结构. C++ 中struct成员访问权限默认为publ ...