iOS笔记052- Quartz2D-绘图

 

简介

Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统数组

Quartz 2D能完成的工做
       绘制图形 : 线条\三角形\矩形\圆\弧等
       绘制文字
       绘制\生成图片(图像)
       读取\生成PDF
       截图\裁剪图片
       自定义UI控件框架

使用Quartz 2D绘制图形须要绘制在UIView上,并且要自定义的view。dom

自定义view的步骤函数

        一、新建一个类,继承自UIViewoop

        二、实现- (void)drawRect:(CGRect)rect方法,而后在这个方法中字体

        三、取得跟当前view相关联的图形上下文动画

        四、绘制相应的图形内容spa

        五、利用图形上下文将绘制的全部内容渲染显示到view上面3d

几种简单的绘图方式

    #pragma mark - 最原始的绘图方式1code

    - (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];

    }

绘制饼状图

首先花圆弧,而后链接圆心,最后填充位一个扇形

屏幕快照 2015 06 21 12 44 58 

    // 饼状图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

    {

        // iOSRGB返回是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];

    }

绘制柱状图

计算方柱个数,平分宽度,高度按占视图比例计算。

屏幕快照 2015 06 21 12 54 31 

    // 柱状图

    - (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];

        }

    }

文本显示

屏幕快照 2015 06 21 12 58 54 

    // 文本显示

    - (void)drawRect:(CGRect)rect

    {

        NSString *str = @"哈尽快回家的客户发动机可舒服哈的尽快发货阿红的健康法哈德减肥哈第三方阿姐回复就爱的客户房间卡地方哈就等哈接电话发掘";

        // 这个方法不会自动换行

    //    [str drawAtPoint:CGPointZero withAttributes:nil];

        // 自动换行

        [str drawInRect:rect withAttributes:nil];

    }

富文本显示

屏幕快照 2015 06 21 12 59 51

    // 富文本:带有状态的文本

    - (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

屏幕快照 2015 06 21 13 03 43 

drawInRect

屏幕快照 2015 06 21 13 03 26

drawAsPatternInrect

屏幕快照 2015 06 21 13 03 53   

裁剪

 屏幕快照 2015 06 21 13 04 30

    // 绘制图形

    - (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的值

    //    比起NSTimerCADisplayLink能够确保系统渲染每一帧的时候咱们的方法都被调用,从而保证了动画的流畅性。

        // 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);

    }

相关文章
相关标签/搜索