1. 程式人生 > >iOS Quartz2D 繪製簡單圖形--線,圓,弧線,貝塞爾曲線,文字

iOS Quartz2D 繪製簡單圖形--線,圓,弧線,貝塞爾曲線,文字

Quartz2D繪製2D圖形
    
    在iOS中常用的繪圖框架就是Quartz2D, Quartz2D是CoreGraphics框架的一部分, 強大的二維影象繪製引擎, Quartz2D在UIKit框架中也有很好的整合, UIKit中的元件都是由CoreGraphics進行繪製的,
    
    iOS中繪圖一般分為以下幾個步驟:
    1. 獲取繪圖上下文
    2. 建立並設定路徑
    3. 將路徑新增到上下文
    4. 設定上下文的狀態
    5. 繪製路徑
    6. 釋放路徑

這裡需要注意的是:

1.Core Graphics是基於C語言的一套框架,開發時無法像使用Obj-C一樣呼叫;

2.在Quartz 2D中凡是使用帶有“Create”或者“Copy”關鍵字方法建立的物件,在使用後一定要

使用對應的方法釋放(由於這個框架基於C語言編寫無法自動釋放記憶體);

3.Quartz 2D是跨平臺的,因此其中的方法中不能使用UIKit中的物件(UIKit只有iOS可用),

例如用到的顏色只能用CGColorRef而不能用UIColor,但是UIKit中提供了對應的轉換方法

4.在C語言中列舉一般以“k”開頭,由於Quartz 2D基於C語言開發,所以它也不例外(引數中

很多列舉都是k開頭的);

5.由於Quartz 2D是Core Graphics的一部分,所以API多數以CG開頭;

6.在使用Quartz 2D繪圖API中所有以“Ref”結尾物件,在宣告時都不必宣告為指標型別;

7.在使用Quartz 2D繪圖API時,凡是“UI”開頭的相關繪圖函式,都是UIKit對Core Graphics的

封裝(主要為了簡化繪圖操作);


   
    圖形上下文CGContextRef代表圖形輸出裝置(繪製的位置), 包含了繪製圖形的一些裝置資訊, Quartz2D中的所有物件最終都會繪製到上下文上(上下文可以是點陣圖Bitmap, PDF,  視窗Window, 層Layer, 列印物件Print)

繪製效果 :

直接上程式碼簡單粗暴, 很好理解, 註釋很全:

//
//  Quartz2DView.m
//  Quartz2DView
//
//  Created by 帝炎魔 on 16/5/25.
//  Copyright © 2016年 帝炎魔. All rights reserved.
//

#import "Quartz2DView.h"

@implementation Quartz2DView


/**
 *  Quartz2D繪製2D圖形
    
    在iOS中常用的繪圖框架就是Quartz2D, Quartz2D是CoreGraphics框架的一部分, 強大的二維影象繪製引擎, Quartz2D在UIKit框架中也有很好的整合, UIKit中的元件都是由CoreGraphics進行繪製的, 
    
    iOS中繪圖一般分為以下幾個步驟:
    1. 獲取繪圖上下文
    2. 建立並設定路徑
    3. 將路徑新增到上下文
    4. 設定上下文的狀態
    5. 繪製路徑
    6. 釋放路徑
    
    圖形上下文CGContextRef代表圖形輸出裝置(繪製的位置), 包含了繪製圖形的一些裝置資訊, Quartz2D中的所有物件最終都會繪製到上下文上(上下文可以是點陣圖Bitmap, PDF,  視窗Window, 層Layer, 列印物件Print)
 
 *
*/




// 繪圖只能在此方法中呼叫, 否則無法得到當前圖形上下文
- (void)drawRect:(CGRect)rect {
  
    // 1. 取得圖形上下文物件
    CGContextRef context = UIGraphicsGetCurrentContext();
    
//     // 2. 建立路徑物件
//    CGMutablePathRef path = CGPathCreateMutable();
//    
//    CGPathMoveToPoint(path, nil, 20, 50); // 設定路徑的起始點
//    CGPathAddLineToPoint(path, nil, 20, 100); // 從起始點開始繪製
//    CGPathAddLineToPoint(path, nil, 300, 100); // 繪製另一條直線, 從上一個直線終點開始繪製
//    
//    // 3. 新增路徑到上下文
//    CGContextAddPath(context, path);
//    
//    // 4, 設定圖形上下文狀態屬性
//    CGContextSetRGBStrokeColor(context, .5, 0, 0, 1); // 設定描邊顏色
//    CGContextSetRGBFillColor(context, 1.0, 0, 0, 1); // 設定填充顏色
//    CGContextSetLineWidth(context, 5.0); // 設定線條的寬度
//    CGContextSetLineCap(context, kCGLineCapRound); // 設定頂點的樣式 (起始點和終點)
//    CGContextSetLineJoin(context, kCGLineJoinBevel); // 設定連線點的樣式(中間點)
//    
//    /**
//     *  設定線段樣式
//        phase : 虛線開始的位置
//        lengths : 虛線長度間隔 
//        count : 虛線陣列元素的個數
//     */
//    CGFloat lengths[2] = {18, 9};
//    CGContextSetLineDash(context, 0, lengths, 2);
//    
//    /**
//     *   設定陰影
//        context : 圖形上下文
//        offset : 陰影的偏移量
//        blur : 模糊度
//        color : 陰影的顏色
//     */
//    CGColorRef color = [UIColor brownColor].CGColor; // 將UIKit的Color轉換下格式
//    CGContextSetShadowWithColor(context, CGSizeMake(10, -10), 0.7, color);
//    
//    // 5. 繪製圖像到指定圖形上下文
//    /**
//     *  CGPathDrawingMode是填充方式,列舉型別
//     kCGPathFill:只有填充(非零纏繞數填充),不繪製邊框
//     kCGPathEOFill:奇偶規則填充(多條路徑交叉時,奇數交叉填充,偶交叉不填充)
//     kCGPathStroke:只有邊框
//     kCGPathFillStroke:既有邊框又有填充
//     kCGPathEOFillStroke:奇偶填充並繪製邊框
//     */
//    CGContextDrawPath(context, kCGPathFillStroke); // 最後一個引數是填充的型別
//    
//    
//    // 釋放物件
//    CGPathRelease(path);
//    CGColorRelease(color);
//    CGContextRelease(context);
    
    
#pragma mark --- 簡化的繪圖方式
    
    // 直線
    [self drawLineWithContext:context];
    
    // 矩形
    [self drawRectWithContext:context];
    
    // 利用UIKit封裝的方法繪製矩形
    [self drawRectByUIKitWithContext:context];
    
    // 繪製橢圓
    [self drawEllipse:context];
    
    
    // 繪製弧形
    [self drawArcWithContext:context];
    
    
    // 繪製貝塞爾曲線
  //  [self drawCurve:context];
    
    // 影象繪製
   // [self drawImage:context];


       
    // 繪製文字
   // [self drawTextWithContext:context];
 }

#pragma mark --- 繪製直線
- (void)drawLineWithContext:(CGContextRef)context
{
    // 1. 繪製路徑
    CGContextMoveToPoint(context, 20, 50);
    CGContextAddLineToPoint(context, 20, 100);
    CGContextAddLineToPoint(context, 300, 100);
    
    // 2. 封閉路徑
    CGContextClosePath(context);
    
    // 3. 設定圖形上下文
    [[UIColor redColor] setStroke]; // 設定描邊顏色
    [[UIColor greenColor] setFill ]; // 設定填充顏色
   // [[UIColor redColor] set] // 同時設定描邊和填充顏色
    
    // 4. 繪製路徑
    CGContextDrawPath(context, kCGPathFillStroke);
}


#pragma mark ---- 繪製矩形
- (void)drawRectWithContext:(CGContextRef)context
{
    // 1. 新增矩形的物件
    CGContextAddRect(context, CGRectMake(100, 120, 200, 20));
    
    // 2. 設定屬性
    [[UIColor redColor] set];
    
    // 3. 繪製
    CGContextDrawPath(context, kCGPathFillStroke);
}

#pragma mark --- 繪製矩形----> 利用UIKit的封裝方法
- (void)drawRectByUIKitWithContext:(CGContextRef)context
{
    [[UIColor brownColor] set];
    
    UIRectFill(CGRectMake(100, 150, 200, 20));
    
    [[UIColor redColor] setStroke];
    UIRectFrame(CGRectMake(100, 200, 200, 20));
    
}

#pragma mark --- 繪製橢圓 
- (void)drawEllipse:(CGContextRef)context
{
    // 新增物件, 繪製橢圓 , 先建立一個矩形
    CGContextAddEllipseInRect(context, CGRectMake(100, 240, 200, 100));
    
    // 設定屬性
    [[UIColor redColor] setStroke];
    [[UIColor greenColor] setFill];
    // 設定描邊的寬度
    CGContextSetLineWidth(context, 5);
    CGContextDrawPath(context, kCGPathFillStroke);
}

#pragma mark --- 繪製弧形
- (void)drawArcWithContext:(CGContextRef)context
{
    /**
     *  新增弧形物件
        x : 中心點的 x座標
        y : 中心點的 y座標
        radius : 半徑
        startAngle : 起始弧度
        endAngle : 終止弧度
        closeWise : 是否逆時針繪製, 0則順時針繪製, 1 逆時針繪製
     */
    CGContextAddArc(context, 200, 450, 50, 0, M_PI * 3 / 2 , 0);
    
    // 設定屬性
    [[UIColor blueColor] set];
    
    // 繪製圖形
    CGContextDrawPath(context, kCGPathFillStroke);
}

#pragma mark ---- 繪製貝塞爾曲線
/**
 *  利用路徑可以繪製直線, 同時利用路徑也可以繪製不規則曲線, 都屬於路徑繪製   
    
    Quartz2D繪製曲線分為兩種, 一個是二次貝塞爾曲線, 還有一個是三次貝塞爾曲線
 
    貝塞爾曲線需要起始點, 終止點 和控制點
 
    二次貝塞爾曲線只有一個控制點, 
    CGContextAddQuadCurveToPoint(CGContextRef c, CGFloat cpx, CGFloat x, CGFloat y);
 
    三次貝塞爾曲線是有兩個控制點
    CGContextAddCurveToPoint(context, CGFloat)
 */
- (void)drawCurve:(CGContextRef)context
{
   // 繪製曲線 設定移動的起始點
    CGContextMoveToPoint(context, 20, 100);
    
    /**
     *  繪製二次貝塞爾曲線
        第一個引數 : 控制點的位置
        第二個引數 : 終止點的位置
     */
    
    CGContextAddQuadCurveToPoint(context, 200, 40, 300, 100);
    
    
    
    // 設定貝塞爾曲線的起始點
    CGContextMoveToPoint(context, 20, 300);
    
    /**
     *  繪製三次貝塞爾曲線
        第一個引數 : 第一個控制點的座標位置
        第二個引數 : 第二個控制點的座標位置
        第三個引數 : 終止點的座標
     */
    
    CGContextAddCurveToPoint(context, 100, 200, 200, 500, 300, 300);
    
    // 設定顏色
    [[UIColor redColor] setFill];
    [[UIColor greenColor] setStroke];
    // 繪製路徑
    CGContextDrawPath(context, kCGPathFillStroke);
    
    
}

#pragma mark --- 將影象繪製到圖形上下文
- (void)drawImage:(CGContextRef)context
{
    
    // 使用UIKit中封裝的方法進行影象繪製 座標原點為左上角
    UIImage *image = [UIImage imageNamed:@"shaonv"];
    // 繪製到指定Rect矩形中
    [image drawInRect:self.bounds];
    
    // 以一個起始點繪製圖片
  // [ image drawAtPoint:<#(CGPoint)#>];
    // 以平鋪式 繪製圖片
    // [image drawAsPatternInRect:self.bounds];
    
    
}

#pragma mark ---- 繪製文字
- (void)drawTextWithContext:(CGContextRef)context
{
    // 繪製到指定區域的內容
    NSString *string = @"Star Walk is the most beautiful stargazing app you’ve ever seen on a mobile device. It will become your go-to interactive astro guide to the night sky, following your every movement in real-time and allowing you to explore over 200, 000 celestial bodies with extensive information about stars and constellations that you find";
    CGRect rect = CGRectMake(20, 50, 280, 300);
    UIFont *font = [UIFont systemFontOfSize:18]; // 設定字型
    UIColor *color = [UIColor redColor]; // 設定字型顏色
    // 設定段落樣式
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    NSTextAlignment align = NSTextAlignmentLeft; // 對齊方式
    style.alignment = align;
    [string drawInRect:rect withAttributes:@{NSFontAttributeName:font, NSForegroundColorAttributeName:color, NSParagraphStyleAttributeName : style}];
}

@end