iOS_Quartz2D_ 基礎

什么是Quartz 2D

1>Quartz 2D是一個二維繪圖引擎,同時支持iOS和Mac OS X系統(跨平臺,純C語言的),包含在Core Graphics框架中.

2> Quartz 2DAPI是純C語言的.數據類型和函數基本都是以CG作為前綴.: CGContextRef, CGPathRef, CGContextStrokePath……

Quartz 2D能完成什么工作?

l1>繪制圖形:線條,三角形,矩形,,,.

l2>繪制文字.

l3>繪制生成圖片(圖像).

l4>讀取\生成PDF.

l5>截圖\裁剪圖片.

l6>自定義UI控件,如環形下載進度條等.

Quartz 2D繪圖主要步驟:

l1>獲取圖形上下文”.

l2>圖形上下文中添加路徑.

l3>渲染.把圖形上下文中的圖形繪制到對應的設備上.

關于圖形上下文CGContextRef中主要包含的信息:

l1>繪圖路徑(各種各樣的圖形).

l2>繪制狀態(顏色,線寬,樣式,旋轉,縮放,平移,圖片裁剪區域等).

l3>輸出目標(繪制到什么地方去?UIView,圖片, pdf,打印機等).





使用Quartz 2D繪圖:

l1>繪圖路徑(各種各樣的圖形).

l2>繪制狀態(顏色,線寬,樣式,旋轉,縮放,平移,圖片裁剪區域等).

l3>輸出目標(繪制到什么地方去??UIView,圖片, pdf,打印機等).

使用方式一直接調用Quartz2D的API進行繪圖

l1>代碼量稍大,功能全面.

l2>步驟如下.

步驟一獲取繪圖上下文

步驟二把圖形繪制到繪圖上下文中

步驟三把繪圖上下文上的圖形渲染到對應的設備上

使用方式二調用UIKit框架封裝好的API進行繪圖

l1>代碼相對簡單,只對部分Quartz2DAPI做了封裝.比如:畫圖片,文字到控件上.

l2>對于沒有封裝的功能只能調用Quartz2D原生的API

DrawRect:方法介紹

l1.為什么向UIView上繪圖,代碼必須寫到drawRect:方法中?

原因:因為只有在view的drawRect:方法中,才能正確的獲取這個view的layer的圖形上下文。

l2.drawRect:方法一定不要自己手動去調用。系統會自動在該調用的時候去調用這個方法。

請問:為什么不能手動去調用這個方法?

1>因為系統在調用drawRect:方法之前,會先創建一個和當前view相關的layer的圖形上下文。這樣的話,在drawRect:這個方法中就可以正確的獲取相應的圖形上下文,然后就可以進行繪圖了。

2>如果手動去調用drawRect:方法,那么在調用drawRect:方法的時候,無法保證和當前view相關的layer的圖形上下文已經創建,所以在drawRect:這個方法中就可能無法正確的獲取相應的圖形上下文,如果沒有圖形上下文,那么也就無法進行繪圖。

l3.如果必須需要重繪的話,怎么辦?

解答:如果必須要進行一次重新繪制,那么也不要直接調用drawRect:方法,而是去調用setNeedsDisplay或者setNeedsDisplayInRect:。這兩個方法內部會先創建一個圖形上下文對象,然后調用drawRect:方法。

l4.drawRect:方法是什么時候調用的?調用幾次?

1>這個方法只在第一次顯示view的時候調用一次

2>如果后續需要重新刷新這個view的顯示,那么需要調用setNeedsDisplay或者setNeedsDisplayInRect:

3>或者是當前view進行重新繪制的時候就會調用drawRect:方法

l5.drawRect:方法中的參數rect指的是什么?

解答:當前繪圖view的bounds。

l6.補充和注意點:

1> UIView內部有個layer(圖層)屬性,drawRect:方法中取得的是一個Layer Graphics Context,因此,繪制的東西其實是繪制到view的layer上去了.

2> UIView之所以能顯示東西,完全是因為它內部的layer.

l7.UIView主要的兩個功能是什么?

1>顯示,為什么UIView可以顯示內容,原因是UIView內部有一個layer,也就是說我們實際上向UIView中繪制的所有內容,其實最終都是畫在了layer上.

2>監聽事件.

案例一Quartz2D簡單演練

展示效果:




請問:實現的步驟是什么?

第一步,在控制器的界面中拖入一個UIView控件,并將類型更改為自定義的類型,重寫drawRect:方法進行繪圖,此時繪制的圖形會被渲染到控件的layer圖層上.

第二步,繪制線條和三角形,使用Quartz 2D原生API來進行繪圖.請問:有哪3個步驟?.

1>獲得圖形上下文

2>拼接路徑

3>渲染

第三步,使用UIKit框架封裝好的UIBezierPath對象來進行繪制圖形.請問:有哪幾個步驟?.

1>獲得圖形上下文

2>創建一個UIBezierPath對象(路徑對象)

3>向UIBezierPath對象中添加若干個路徑

4>把UIBezierPath添加到對應的圖形上下文中

5>渲染

第四步,繪制矩形框.

//代碼實現使用Quartz2D原生API來進行繪圖

------------------------------HMDrawingView.m------------------------------

//

Only override drawRect: if you perform custom drawing.An empty implementation

adversely affects performance during animation.

//僅僅只應該在自定義繪圖的時候重寫drawRect:該方法.如果僅僅重寫該方法,而不執行任何代碼,那么在執行動畫期間會產生一些不利的影響.

```

- (void)drawRect:(CGRect)rect {

// 1.獲取圖形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

/**********路徑信息**********/

// 2.向圖形上下文中添加路徑-繪制一個三角形

// 2.1移動到一個起始點

CGContextMoveToPoint(ctx,50,50);

// 2.2添加一條線到某個點

CGContextAddLineToPoint(ctx,150,50);

// 2.3再添加一條線段

CGContextAddLineToPoint(ctx,50,200);

// 2.4再添加一條線段

//CGContextAddLineToPoint(ctx, 50, 50);

// 2.5關閉路徑

CGContextClosePath(ctx);

//在添加一個新的線段

// 2.6移動到一個新的起點-繪制一條線

CGContextMoveToPoint(ctx,50,260);

// 2.7添加一條線段

CGContextAddLineToPoint(ctx,260,260);

/**********狀態信息**********/

//設置線條的狀態

CGContextSetLineWidth(ctx,20);

//設置線頭樣式

CGContextSetLineCap(ctx,kCGLineCapRound);

//線段連接處的樣式

CGContextSetLineJoin(ctx,kCGLineJoinRound);

//設置線條的顏色

[[UIColorredColor]setStroke];//空心

[[UIColoryellowColor]setFill];//實心

//設置stroke & fill顏色

[[UIColorblueColor]set];

// 3.渲染

CGContextStrokePath(ctx);//空心渲染

CGContextFillPath(ctx);//實心渲染

}

```

//代碼實現使用UIKit框架封裝好的UIBezierPath對象來進行繪制圖形

------------------------------HMDrawingView.m------------------------------

```

- (void)drawRect:(CGRect)rect {

// 1.獲取圖形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

// 2.創建一個UIBezierPath對象(路徑對象)

UIBezierPath*path = [UIBezierPathbezierPath];

// 3.向UIBezierPath對象中添加若干個路徑

[pathmoveToPoint:CGPointMake(50,50)];

[pathaddLineToPoint:CGPointMake(150,50)];

[pathaddLineToPoint:CGPointMake(50,150)];

[pathclosePath];

// 4.把UIBezierPath添加到對應的圖形上下文中

CGContextAddPath(ctx, path.CGPath);

// 5.渲染

CGContextStrokePath(ctx);

}

//步驟四繪制“矩形框”使用Quartz 2D原生API來進行繪圖

- (void)drawRect:(CGRect)rect {

// 1.獲取圖形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

// 2.繪制矩形框

CGContextAddRect(ctx,CGRectMake(50,50,100,100));

// 3.渲染

CGContextStrokePath(ctx);

}

//步驟四使用UIKit框架封裝好的UIBezierPath對象來進行繪制圖形

- (void)drawRect:(CGRect)rect {

// 1.獲取圖形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

// 2.創建路徑對象

UIBezierPath*path = [UIBezierPathbezierPathWithRect:CGRectMake(50,50,100,100)];

// 3.把路徑添加到上下文中

CGContextAddPath(ctx, path.CGPath);

// 4.渲染

CGContextStrokePath(ctx);

}

```

//其它演練–核心代碼




//繪制圓角矩形框

UIBezierPath*path =

[UIBezierPathbezierPathWithRoundedRect:CGRectMake(50,50,150,150)cornerRadius:20];//如果這里的圓角半徑寫成寬度高度的一半,那么就是一個圓

//繪制一個圓形

UIBezierPath*path =

[UIBezierPathbezierPathWithOvalInRect:CGRectMake(50,50,150,150)];

//繪制扇形

1> center :圓心

2> redius :半徑

3> startAngle :起始角度

4> endAngle :結束角度

5> clockwise : YES ->順時針旋轉NO ->逆時針旋轉

UIBezierPath*path =

[UIBezierPathbezierPathWithArcCenter:CGPointMake(150,150)radius:100startAngle:0endAngle:M_PIclockwise:YES];

Even-Odd


展示效果

rule :奇偶填充規則

當一個點被覆蓋過奇數次則“填充”,偶數次則“不填充”.

```

//代碼實現

- (void)drawRect:(CGRect)rect {

// 1.獲取圖形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

// 2.繪制路徑

UIBezierPath*path1 = [UIBezierPathbezierPathWithRect:CGRectMake(250,30,20,200)];

UIBezierPath*path2 = [UIBezierPathbezierPathWithArcCenter:CGPointMake(200,150)radius:80startAngle:0endAngle:M_PI*2clockwise:YES];

UIBezierPath*path3 = [UIBezierPathbezierPathWithRect:CGRectMake(100,100,200,100)];

// 3.添加路徑

CGContextAddPath(ctx, path1.CGPath);

CGContextAddPath(ctx, path2.CGPath);

CGContextAddPath(ctx, path3.CGPath);

// 4.渲染

//說明:被覆蓋過奇數次數的點填充,被覆蓋過偶數次的點不填充

CGContextDrawPath(ctx,kCGPathEOFill);

}

```

nonzero

winding number rule :非零繞數規則


當一個點被從左到右覆蓋過標記為1,從右到左覆蓋過標記為-1,當標記為0的時候不填充,其它則填充.簡單總結,這個規則與方向有關,與次數無關.

//代碼實現

```

- (void)drawRect:(CGRect)rect

{

// 1.獲取圖形上下文

CGContextRefctx =UIGraphicsGetCurrentContext();

// 2.繪制路徑

UIBezierPath*path1 = [UIBezierPathbezierPathWithArcCenter:CGPointMake(150,150)radius:100startAngle:0endAngle:M_PI*2clockwise:YES];

UIBezierPath*path2 = [UIBezierPathbezierPathWithArcCenter:CGPointMake(150,150)radius:50startAngle:0endAngle:M_PI*2clockwise:NO];

// 3.添加路徑

CGContextAddPath(ctx,

path1.CGPath);

CGContextAddPath(ctx, path2.CGPath);

// 4.渲染

CGContextDrawPath(ctx,kCGPathFill);

}

```

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容

  • 第一步:先科普一下基礎知識: Core Graphics是基于C的API,可以用于一切繪圖操作 Core Grap...
    真愛要有你才完美閱讀 2,463評論 0 1
  • Quartz2D以及drawRect的重繪機制字數1487 閱讀21 評論1 喜歡1一、什么是Quartz2D Q...
    PurpleWind閱讀 786評論 0 3
  • 什么是Quartz2D 是一個二維的繪圖引擎,同時支持iOS和Mac系統 Quartz2D的API是純C語言的,它...
    Mario_ZJ閱讀 599評論 0 1
  • 1每天一套一遍真題,過幾天結合一千題大量刷題。 2把小本看完,每天堅持鉆研真題與背單詞。 3每天堅持背,大量背,默...
    最后幾天閱讀 94評論 0 0
  • 我們的每一次相遇都是一天又一天的緩慢告別。時間讓愛我們的人和我們的愛人漸行漸遠,而我們卻無力去改變什么。 找核心 ...
    93650345d0d1閱讀 137評論 0 0