简介

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-绘图的更多相关文章

  1. iOS:quartz2D绘图

    Quartz-2D:绘图 一.介绍: •Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境   •Quartz 2D API可以实现许多功能,如基于路径的绘图.透明度.阴影 ...

  2. iOS开发之Quartz2D详解

    1. 什么是Quartz2D? Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片( ...

  3. iOS开发之Quartz2D

    1.         Quartz2D概述及作用 Quartz2D的API是纯C语言的,Quartz2D的API来自于Core Graphics框架. 数据类型和函数基本都以CG作为前缀,比如: CG ...

  4. 阶段性总结⓵触摸事件&手势识别⓶Quartz2D绘图⓷CALayer图层⓸CAAnimation⓹UIDynamic UI动力学⓺KVC&KVO

    知识点复习   1. 触摸事件&手势识别   1> 4个触摸事件,针对视图的 2> 6个手势识别(除了用代码添加,也可以用Storyboard添加)   附加在某一个特定视图上的, ...

  5. WPF笔记(1.10 绘图)——Hello,WPF!

    原文:WPF笔记(1.10 绘图)--Hello,WPF! 书中的代码语法过时了,改写为以下(测试通过):         <Button>            <Button.L ...

  6. iOS基础 - Quartz 2D绘图的基本步骤

    一.使用Quartz 2D绘图的基本步骤 1) 获取上下文context(绘制图形的地方) 2) 设置路径(路径是用来描述形状的) 3)  将路径添加到上下文 4)  设置上下文属性(设置颜色,线宽, ...

  7. matlab学习笔记9 高级绘图命令_2 图形的高级控制_视点控制和图形旋转_色图和颜色映像_光照和着色

    一起来学matlab-matlab学习笔记9 高级绘图命令_2 图形的高级控制_视点控制和图形旋转_色图和颜色映像_光照和着色 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 < ...

  8. matlab学习笔记9 高级绘图命令_1 图形对象_根对象,轴对象,用户控制对象,用户菜单对象

    一起来学matlab-matlab学习笔记9 高级绘图命令_1 图形对象_根对象,轴对象,用户控制对象,用户菜单对象 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matl ...

  9. matlab学习笔记8 基本绘图命令-三维绘图

    一起来学matlab-matlab学习笔记8 基本绘图命令_6 三维绘图 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用>张德丰等著 ...

  10. matlab学习笔记8 基本绘图命令-初级二维绘图/交互式绘图

    一起来学matlab-matlab学习笔记8 基本绘图命令_5 初级二维绘图/交互式绘图 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用&g ...

随机推荐

  1. spark集群配置细则总结

    修改目录与目录组: sudo chown -R hadoop:hadoop spark-1.6.1-bin-hadoop2.6 sudo chown -R hadoop:hadoop jdk1.8.0 ...

  2. LeetCode Longest Substring Without Repeating Characters 最长不重复子串

    题意:给一字符串,求一个子串的长度,该子串满足所有字符都不重复.字符可能包含标点之类的,不仅仅是字母.按ASCII码算,就有2^8=128个. 思路:从左到右扫每个字符,判断该字符距离上一次出现的距离 ...

  3. pat甲级1013

    1013 Battle Over Cities (25)(25 分) It is vitally important to have all the cities connected by highw ...

  4. linux 命令——53 route(转)

    Linux系统的route 命令用于显示和操作IP路由表(show / manipulate the IP routing table).要实现两个不同的子网之间的通信,需 要一台连接两个网络的路由器 ...

  5. linux下安装和卸载mysql

      卸载: 1 . rpm -qa | grep -i mysql命令查看已经安装过的组件.   2. 使用yum -y remove命令卸载已经安装的MySQL组件,使用下面的命令,对于上面已经安装 ...

  6. 【洛谷3157】[CQOI2011] 动态逆序对(CDQ分治)

    点此看题面 大致题意: 给你一个从\(1\)到\(n\)的排列,问你每次删去一个元素后剩余的逆序对个数. 关于\(80\)分的树套树 为了练树套树,我找到了这道题目. 但悲剧的是,我的 线段树套\(T ...

  7. python剑指offer 顺时针打印指针

    题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数 ...

  8. 2.3.3 zerosum 和为零

    #include<bits/stdc++.h> using namespace std; ],a; ]={' ','+','-'}; void out() { ;i<a;i++) c ...

  9. django+xadmin在线教育平台(五)

    3-3 django orm介绍与model设计 上节教程完成后代码(来学习本节前置条件): 对应commit: 留言板前端页面展示.本次内容截止教程3-2结束. 可能现在你还在通过手写sql语句来操 ...

  10. js数据结构与算法--递归

    递归,函数自己调用自己 return 返回值, 后面的代码不执行 function fn(num){ console.log(num) if(num == 0){ return; } fn(num-1 ...