你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS——Quartz2D

iOS——Quartz2D

編輯:IOS開發綜合

1.基本圖形繪制

* 線段(線寬、線段樣式)

* 矩形(空心、實心、顏色)

* 三角形、四邊形等形狀

 

1> 說明 - (void)drawRect:(CGRect)rect 什麼時候調用、調用次數等

- 當 view 第一次被顯示的時候調用(調用一次)

- 或者是重繪事件被觸發的時候

- 不要手動去調用這個方法

- 手動調用重繪方法 setNeedsDisplay 或者 setNeedsDisplayInRect:

 

2> 說明為什麼要在 - (void)drawRect:(CGRect)rect 方法中進行繪圖

- 只有在這個方法中才能獲取當前 View 的繪圖上下文

 

/**

1. 當要向UIView上繪圖的時候, 必須重寫UIView的drawRect:方法, 然後在這個方法中進行繪圖

2. 在drawRect:方法中獲取的參數rect, 指的就是當前view的bounds屬性

3. 為什麼向當前view中繪制圖形, 必須在drawRect:方法中進行?

3.1 原因: 只有在當前view的drawRect:方法中才能成功的獲取當前view的"圖形上下文", 有了圖形上下文才能進行繪圖

3.2 為什麼只有在drawRect:方法中才能獲取當前view的圖形上下文呢?

3.3 原因: 是因為系統在調用drawRect:方法之前已經幫我們創建好了一個與當前view相關的圖形上下文了, 然後才調用的drawRect:方法, 所以在drawRect:方法中, 我們就可以成功獲取當前view的圖形上下文了。

3.4 如何創建一個圖形上下文?(後面說)

3.5 drawRect:方法是誰來調用的?什麼時候調用的?

3.5.1 drawRect:方法是系統幫我們調用的, 千萬別手動去調用這個方法。原因是, 自己手動去調用drawRect:方法的時候無法保證系統已經幫我們創建好了"圖形上下文", 所以這樣就無法保證在drawRect:方法中獲取"圖形上下文"對象, 所以也就無法繪圖。

3.5.2 drawRect:方法的什麼時候被調用?

1> 當這個View第一次顯示的時候會條用一次drawRect:方法。

2> 當這個View執行重繪操作的時候, 會重新調用drawRect:方法來進行繪圖。

3> 通過調用【[self setNeedsDisplay];// 把這個view都重繪一次】 或 【[self setNeedsDisplayInRect:(CGRect)]// 把view中的某個區域重繪一次】 來實現重繪

4> 在每次調用 setNeedsDisplay 或 setNeedsDisplayInRect:方法的時候, 內部會先創建一個與當前view相關連的"圖形上下文"然後再調用drawRect:實現重繪。

*/

 

案例:

1> 繪制一根線段

/** 參考代碼:

 

void test1()

{

// 1. 獲取當前的圖形上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 在上下文中繪制圖形(拼接路徑)

// 2.1 設置一個起點

CGContextMoveToPoint(ctx, 20, 20);

// 2.2 添加一條直線到(100, 100)這個點

CGContextAddLineToPoint(ctx, 100, 20);

 

 

// 3. 把上下文渲染顯示到 HMView01上

// StrokePath 表示把路徑以空心的形式渲染出來。

CGContextStrokePath(ctx);

}

 

*/

 

2> 繪制一個中文"二", 兩根線段

/** 參考代碼:

 

void test2()

{

// 1. 獲取當前的圖形上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 在上下文中繪制圖形(拼接路徑)

// 2.1 設置一個起點

CGContextMoveToPoint(ctx, 20, 20);

// 2.2 添加一條直線到(100, 100)這個點

CGContextAddLineToPoint(ctx, 100, 20);

 

 

// 2.3 再重新設置一個起點

CGContextMoveToPoint(ctx, 5, 50);

// 2.4 再添加一條線

CGContextAddLineToPoint(ctx, 115, 50);

 

 

// 3. 把上下文渲染顯示到 HMView01上

// StrokePath 表示把路徑以空心的形式渲染出來。

CGContextStrokePath(ctx);

}

 

*/

 

3> 繪制一個"三角形"

/** 參考代碼:

 

void test3()

{

// 1. 獲取當前的圖形上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 在上下文中繪制圖形(拼接路徑)

// 2.1 設置一個起點

CGContextMoveToPoint(ctx, 20, 20);

// 2.2 添加一條直線到(100, 100)這個點

CGContextAddLineToPoint(ctx, 100, 100);

 

// 2.3 再添加一條線

CGContextAddLineToPoint(ctx, 120, 30);

 

// 2.4 再添加一條線段

//CGContextAddLineToPoint(ctx, 20, 20);

// 另外一種做法: 直接關閉路徑(連接最後一個點和起點)

CGContextClosePath(ctx);

 

 

// 3. 把上下文渲染顯示到 HMView01上

// StrokePath 表示把路徑以空心的形式渲染出來。

CGContextStrokePath(ctx);

}

 

*/

 

4> 繪制一個"矩形"。

* 思路1: 可以畫4根線來表示一個矩形。

/** 參考代碼:

// 繪制四邊形, 這種畫法, 只能話"正"的圖形, "斜"的需要使用"矩陣"的方式來進行旋轉

void test4()

{

// 繪制一個"四邊形"

// 1. 獲取當前圖形上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 開始繪制路徑

CGContextAddRect(ctx, CGRectMake(20, 20, 100, 120));

 

// 3. 渲染

CGContextStrokePath(ctx);

}

*/

 

5> 繪制一個實心"矩形"

/** 參考代碼:

// 繪制"實心"矩形, 只要把 Stroke 變成 Fill 即可

void test5()

{

// 繪制一個"四邊形"

// 1. 獲取當前圖形上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 開始繪制路徑

CGContextAddRect(ctx, CGRectMake(20, 20, 100, 120));

 

// 3. 渲染

CGContextFillPath(ctx);

 

}

*/

6.1> 設置圖形的顏色

/** 參考代碼:

 

// 設置圖形的顏色

void test6()

{

// 繪制一個"四邊形"

// 1. 獲取當前圖形上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 開始繪制路徑

CGContextAddRect(ctx, CGRectMake(20, 20, 100, 120));

//============ C 語言的方式設置顏色 =================

 

CGContextSetRGBFillColor(ctx, 200/255.0, 100/255.0, 50/255.0, 1.0);

//CGContextSetRGBStrokeColor(<#CGContextRef context#>, <#CGFloat red#>, <#CGFloat green#>, <#CGFloat blue#>, <#CGFloat alpha#>)

 

//============ C 語言的方式設置顏色 =================

 

 

 

//============ OC 的方式設置顏色 =================

// 設置空心圖形的線條顏色

// [[UIColor redColor] setStroke];

 

// 設置實心圖形的填充顏色

// [[UIColor redColor] setFill];

 

// 統一設置"空心圖形" 和 "實心圖形"的顏色

//[[UIColor redColor] set];

//============ OC 的方式設置顏色 =================

// 3. 渲染

CGContextFillPath(ctx);

}

*/

 

 

6.2> 設置不同線段, 不同顏色

/** 參考代碼:

 

void test8()

{

//畫兩根線, 一根紅色, 一根藍色

// 1. 獲取上下文對象

CGContextRef ctx = UIGraphicsGetCurrentContext();

// 2. 繪制圖形

// 2.1 設置起點

CGContextMoveToPoint(ctx, 50, 50);

// 2.2 添加一根線

CGContextAddLineToPoint(ctx, 50, 150);

 

// 2.3 設置線段顏色

[[UIColor redColor] set];

// 2.4 設置線寬

CGContextSetLineWidth(ctx, 10);

// 渲染一次

CGContextStrokePath(ctx);

// 再移動到一個新的起點

CGContextMoveToPoint(ctx, 100, 50);

// 再添加一根線

CGContextAddLineToPoint(ctx, 100, 150);

// 設置線的顏色

[[UIColor blueColor] set];

 

 

// 3. 渲染"上下文對象"到 view 上

CGContextStrokePath(ctx);

}

 

*/

 

 

 

7> 設置線段寬度(也可以使用這種方式繪制"實心矩形")

/** 參考代碼:

 

// 設置線段寬度

void test7()

{

// 繪制一個"四邊形"

// 1. 獲取當前圖形上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 開始繪制路徑

CGContextAddRect(ctx, CGRectMake(20, 20, 100, 120));

 

// 設置空心圖形的線條顏色

// [[UIColor redColor] setStroke];

 

// 設置實心圖形的填充顏色

// [[UIColor redColor] setFill];

 

// 統一設置"空心圖形" 和 "實心圖形"的顏色

[[UIColor redColor] set];

 

// 設置線段寬度

CGContextSetLineWidth(ctx, 20);

 

// 3. 渲染

CGContextStrokePath(ctx);

}

*/

 

 

* 解釋:

1> 拼接路徑

/** 參考代碼:

 

// 2. 在上下文中繪制圖形(拼接路徑)

// 2.1 設置一個起點

CGContextMoveToPoint(ctx, 20, 20);

// 2.2 添加一條直線到(100, 100)這個點

CGContextAddLineToPoint(ctx, 100, 100);

 

// 2.3 再添加一條線

CGContextAddLineToPoint(ctx, 120, 30);

 

*/

2> 設置狀態

/** 參考代碼:

 

// 統一設置"空心圖形" 和 "實心圖形"的顏色

[[UIColor redColor] set];

 

// 設置線段寬度

CGContextSetLineWidth(ctx, 20);

 

 

*/

8> 設置線段"頭尾部"的樣式

/** 參考代碼:

 

void test9()

{

// 1. 獲取上下文對象

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 繪制路徑

// 2.1 移動到起點

CGContextMoveToPoint(ctx, 20, 20);

 

// 2.2 添加一條線段

CGContextAddLineToPoint(ctx, 100, 100);

 

// 2.3 設置顏色

[[UIColor redColor] set];

 

 

// 2.4 設置線段寬度

CGContextSetLineWidth(ctx, 15);

 

// 2.5 設置線段頭尾部樣式

 

//enum CGLineCap {

//kCGLineCapButt, 默認值

//kCGLineCapRound, 圓角

//kCGLineCapSquare 方角

//};

 

CGContextSetLineCap(ctx, kCGLineCapSquare);

 

 

// 3. 渲染

CGContextStrokePath(ctx);

}

*/

 

9> 設置轉折點樣式

/** 參考代碼:

 

void test10()

{

// 1. 獲取上下文對象

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 繪制路徑

// 2.1 移動到起點

CGContextMoveToPoint(ctx, 20, 20);

 

// 2.2 添加一條線段

CGContextAddLineToPoint(ctx, 100, 100);

// 2.3 再添加一條線段

CGContextAddLineToPoint(ctx, 150, 50);

 

 

// 2.3 設置顏色

[[UIColor redColor] set];

 

 

// 2.4 設置線段寬度

CGContextSetLineWidth(ctx, 15);

 

// 2.5 設置線段頭尾部樣式

CGContextSetLineCap(ctx, kCGLineCapRound);

// 2.6 設置轉折點樣式

CGContextSetLineJoin(ctx, kCGLineJoinBevel);

 

 

// 3. 渲染

CGContextStrokePath(ctx);

}

 

 

*/

* 橢圓\圓

1> 橢圓\圓

/** 參考代碼: 思路, 圓其實就是一個在在矩形中的圖形。

// 繪制圓和橢圓

void test()

{

// 1. 獲取上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 繪制圖形

// 橢圓

CGContextAddEllipseInRect(ctx, CGRectMake(10, 20, 150, 100));

// 圓

CGContextAddEllipseInRect(ctx, CGRectMake(30, 50, 100, 100));

 

// 3. 渲染

CGContextStrokePath(ctx);

}

*/

 

2> 繪制圓環:

* 思路1: 在畫圓的時候, 設置線寬即可。CGContextSetLineWidth(ctx, 20);

* 思路2: 畫兩個嵌套的圓

 

 

 

3> 畫不同的圓弧

* 畫上面半個圓弧

* 畫下面半個圓弧

* 畫右下角的1/4圓弧

* 左側半圓弧

* 右側半圓弧

* 左下角的1/4的圓弧

* 畫一個圓

/** 參考代碼:

// 畫不同的圓弧

void test2()

{

// 1. 獲取上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 繪制圖形

// 畫圓弧

// ios 系統中坐標系剛好是反的所以指定了1(順時針)反而效果是"逆時針"。

//CGContextAddArc(ctx, 100, 100, 50, 0, M_PI, 0);

//CGContextAddArc(ctx, 100, 100, 50, 0, M_PI * 0.5, 0);

//CGContextAddArc(ctx, 100, 100, 50, -M_PI_2, M_PI_2, 0);

// 繪制左下角的1/4的圓弧

//CGContextAddArc(ctx, 100, 100, 50, M_PI, M_PI_2, 1);

// 畫一個圓

//CGContextAddArc(ctx, 100, 100, 50, 0, M_PI * 2, 1);

 

// 3. 渲染

CGContextStrokePath(ctx);

}

 

*/

 

4> 演示

/** 參考代碼:

 

 

- (void)drawRect:(CGRect)rect {

 

// 1. 獲取上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 繪制圖形

// 繪制左下角的1/4的圓弧

CGContextAddArc(ctx, 100, 100, 50, M_PI, M_PI_2, 1);

 

// 3. 渲染

CGContextFillPath(ctx);

}

 

*/

 

5> 畫一個左下角1/4 的實心圓

/** 參考代碼:

 

- (void)drawRect:(CGRect)rect {

 

// 1. 獲取上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 2. 繪制圖形

// 繪制左下角的1/4的圓弧

CGContextAddArc(ctx, 100, 100, 50, M_PI, M_PI_2, 1);

// 添加一根線

CGContextAddLineToPoint(ctx, 100, 100);

// 關閉路徑

CGContextClosePath(ctx);

 

// 3. 渲染

CGContextFillPath(ctx);

}

 

*/

* 文字繪制(通過OC 來繪制圖形)

1> 繪制一段文字(思路: 直接使用 OC 的方法, 無需手動獲取上下文對象)

/** 參考代碼:

 

- (void)drawRect:(CGRect)rect {

NSString *str = @"哈哈, 黑馬程序員 iOS學院。";

 

NSDictionary *attrs = @{

NSForegroundColorAttributeName : [UIColor redColor],

NSFontAttributeName : [UIFont systemFontOfSize:20]

};

 

[str drawAtPoint:CGPointMake(30, 50) withAttributes:attrs];

}

*/

2> 繪制一段文字到一個指定的區域

* 思路: 調用字符串的 drawInRect: 方法.

/** 參考代碼:

 

- (void)drawRect:(CGRect)rect {

 

 

// 1. 繪制文字

NSString *str = @"哈哈, 黑馬程序員 iOS。";

 

NSDictionary *attrs = @{

NSForegroundColorAttributeName : [UIColor redColor],

NSFontAttributeName : [UIFont systemFontOfSize:20]

};

 

[str drawInRect:CGRectMake(20, 20, 50, 250) withAttributes:attrs];

// 1. 獲取上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

// 2. 把矩形畫出來

CGContextAddRect(ctx,CGRectMake(20, 20, 50, 250));

 

// 3. 渲染

CGContextStrokePath(ctx);

}

 

*/

* 圖片繪制(通過OC 來繪制圖形)

1> 繪制一張圖片到 UIView 上。

* 思路: 通過 OC 的方法來實現。

/** 參考代碼:

- (void)drawRect:(CGRect)rect {

// 1. 獲取圖片

UIImage *img = [UIImage imageNamed:@"dst2"];

// 2. 把圖片畫到當前的 view中

[img drawAtPoint:CGPointMake(0, 0)];

}

*/

 

2. 在指定的矩形中繪制圖片(會自動拉伸)

/** 參考代碼:

- (void)drawRect:(CGRect)rect {

 

// 1. 獲取圖片

UIImage *img = [UIImage imageNamed:@"dst2"];

// 2. 把圖片畫到當前的 view中

[img drawInRect:CGRectMake(0, 0, 150, 150)];

 

}

*/

3. 畫格子花紋效果((pattern)), 思路: 調用drawAsPatternInRect:方法

/** 參考代碼:

- (void)drawRect:(CGRect)rect {

// 1. 獲取圖片

UIImage *img = [UIImage imageNamed:@"abc"];

 

// 2. 把圖片畫到當前的 view中

[img drawAsPatternInRect:self.bounds];

 

// 3. 在右下角顯示文字

NSString *str = @"@傳智播客 ios 學院";

NSDictionary *attrs = @{

NSForegroundColorAttributeName : [UIColor redColor],

NSFontAttributeName : [UIFont systemFontOfSize:20]

};

 

[ str drawInRect:CGRectMake(0, 100, 200, 30) withAttributes:attrs];

}

*/

* 在指定的區域畫一張圖片, 然後再在指定的區域畫一些文字(水印)

/** 參考代碼:

 

- (void)drawRect:(CGRect)rect {

// Drawing code

 

// 在指定的區域內畫一張圖片

UIImage *img = [UIImage imageNamed:@"dst2"];

[img drawInRect:self.bounds];

 

 

// 在指定的區域畫一些文字

NSString *str = @"傳智播客 iOS 學院。";

[str drawInRect:CGRectMake(10, 400, 200, 30) withAttributes:nil];

 

}

*/

* 圖形上下文棧

1> 畫兩根線, 設置線的顏色、寬度、頭尾的樣式 LineCap

2> 要求, 第二根線不具有第一根線的樣式。

3> 解決, 在畫第一根線之前先保存"繪圖上下文棧", 在畫第二根線的時候再恢復繪圖上下文棧

CGContextSaveGState(ctx);// 保存ctx這個繪圖上下文對象

CGContextRestoreGState(ctx); // 恢復 ctx這個圖形上下文

* 矩陣操作

1> 整體旋轉、整體縮放

* 思路: 隨便在一個 UIView 上畫一些圖形(線段、矩形、圓等)

/** 參考代碼:

 

- (void)drawRect:(CGRect)rect {

// Drawing code

// 1. 獲取上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

//======================= 矩陣操作 ============================

// 1.1 旋轉

CGContextRotateCTM(ctx, M_PI_4 * 0.5);

// 1.2 縮放

CGContextScaleCTM(ctx, 0.5, 0.5);

//======================= 矩陣操作 ============================

 

// 2. 繪制一些圖形

CGContextMoveToPoint(ctx, 10, 10);

CGContextAddLineToPoint(ctx, 100, 100);

CGContextAddEllipseInRect(ctx, CGRectMake(130, 150, 100, 100));

CGContextAddRect(ctx, CGRectMake(70, 90, 100, 80));

 

 

// 3. 渲染

CGContextStrokePath(ctx);

 

}

 

*/

2> 最後畫的那個圖形不要矩陣操作

* 思路: 在繪制任何圖形前保存上下文, 在繪制最後一個圖形前恢復上下文

/** 參考代碼:

- (void)drawRect:(CGRect)rect {

// Drawing code

// 1. 獲取上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 保存上下文

CGContextSaveGState(ctx);

 

//======================= 矩陣操作 ============================

// 1.1 旋轉

CGContextRotateCTM(ctx, M_PI_4 * 0.5);

// 1.2 縮放

CGContextScaleCTM(ctx, 0.5, 0.5);

//======================= 矩陣操作 ============================

 

// 2. 繪制一些圖形

CGContextMoveToPoint(ctx, 10, 10);

CGContextAddLineToPoint(ctx, 100, 100);

CGContextAddEllipseInRect(ctx, CGRectMake(130, 150, 100, 100));

// 恢復上下文

CGContextRestoreGState(ctx);

 

CGContextAddRect(ctx, CGRectMake(70, 90, 100, 80));

// 3. 渲染

CGContextStrokePath(ctx);

 

}

 

*/

 

* 圖片裁剪

1> 把一個圖片裁剪成圓形

** 思路:

- 在 UIView 上繪制一個25 * 25的圓

- 裁剪上下文

— 加載圖片, 把圖片繪制到 "上下文" 上, 就自動實現了裁剪了

 

/** 參考代碼:

 

- (void)drawRect:(CGRect)rect {

// Drawing code

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

// 1. 畫圓,這裡最好使用 Ellipse 來繪制圓(畫圓和畫圖片都從0,0點開始)。

CGContextAddArc(ctx, 100, 100, 90, 0, M_PI * 2, 1);

 

// 2. 裁剪上下文, 注意裁剪完畢就只能在裁剪好的區域內畫東西了, 超出的地方無法繪制圖形。

CGContextClip(ctx);

 

// 3. 把圖片繪制上去

UIImage *img = [UIImage imageNamed:@"dst2"];

[img drawAtPoint:CGPointMake(0, 0)];

}

 

*/

* 重繪案例: 調整 slider 滑動條, 同時改變圓的大小

1> 思路: 讓繪制圓時, 半徑隨著 slider 的變化而變化

* setNeedsDisplay 方法會把之前的內容都清除掉, 然後再重繪。

* setNeedsDisplayInRect:<#(CGRect)#>局部刷新

/** 參考代碼:

 

- (void)setRadius:(CGFloat)radius

{

_radius = radius;

[self setNeedsDisplay];

}

- (void)drawRect:(CGRect)rect {

// Drawing code

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

CGContextAddArc(ctx, 100, 100, self.radius, 0, M_PI * 2, 1);

 

CGContextFillPath(ctx);

 

}

 

*/

 

3.模仿UIImageView

* 思路:

1> 演示 UIImageView 的基本用法

2> 自定義一個類繼承自 UIView, 添加一個 image 屬性

 

/** 參考代碼:

// 1. 控制器

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

MyImageView *imgView =[[MyImageView alloc] init];

imgView.image = [UIImage imageNamed:@"dst2"];

imgView.frame = CGRectMake(30, 30, 100, 100);

[self.view addSubview:imgView];

 

self.myImgView = imgView;

 

}

 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

self.myImgView.image = [UIImage imageNamed:@"snow"];

}

// 2. 自定義 view

- (void)setImage:(UIImage *)image

{

_image = image;

[self setNeedsDisplay];

}

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

// Drawing code

[self.image drawAtPoint:CGPointZero];

}

*/

 
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved