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

    }

相關文章
相關標籤/搜索