來來來钓葫,好玩的東西終于來了悄蕾。接下來的幾篇,咱們都將要聊一聊iOS中繪制圖像的事兒哈。之前有一篇說到cell分割線頂頭的方法中帆调,有童鞋留言說還可以自己繪制奠骄。咳咳番刊,會了繪圖這個就不是難事兒啦~
還有很多App里面超炫的特效含鳞,其實(shí)也都是基于各種繪圖、路徑噠芹务。來吧蝉绷,騷年~讓我們浪起來。
在此之前枣抱,分享了一些關(guān)于繪圖方面的基礎(chǔ)潜必。可以通過傳輸門快捷進(jìn)入:
1. Quartz2D
- Quartz 2D是一個二維繪圖引擎磁滚,同時支持iOS和Mac OS X系統(tǒng)(跨平臺,純 C 語言的)宵晚。包含在 Core Graphics 框架中垂攘。
- Quartz 2D能完成的工作
- 繪制圖形 : 線條\三角形\矩形\圓\弧等
- 繪制文字
- 繪制\生成圖片(圖像)
- 讀取\生成PDF
- 截圖\裁剪圖片
- 餅狀圖、柱狀圖淤刃、折線圖
- 自定義UI控件
注意:
Quartz 2D 是蘋果官方的二維繪圖引擎晒他,同時支持 iOS 和 Mac OS X 系統(tǒng)。
Cocos2D(Cocos2D-x逸贾、Cocos2D-iPhone陨仅、Cocos2D-HTML5等), Cocos2D 是一個第三方開源的2D游戲框架。做2D 游戲的 還有 Sprite Kit铝侵。 一般3D 游戲用 unity3D灼伤。
1.1 Quartz2D 繪圖主要步驟
獲取【context】對象
向【context】對象中添加【路徑】
渲染(把【context】中的圖形會知道對應(yīng)的設(shè)備上)
一定要自定義一個view,把contxt和執(zhí)行渲染的方法都放在自定義的view中
1.2 drawRect:
- 為什么要實(shí)現(xiàn)drawRect:方法才能繪圖到view上咪鲜?
因?yàn)樵赿rawRect:方法中才能取得跟view相關(guān)聯(lián)的context
- drawRect:方法在什么時候被調(diào)用狐赡?
當(dāng)view第一次顯示到屏幕上時(加到UIWindow上顯示出來)
重繪的時候:調(diào)用view的setNeedsDisplay
或者setNeedsDisplayInRect:
時
1.3 Graphics Context
Graphics Context 是一個數(shù)據(jù)類型(CGContextRef),用于封裝 Quartz 繪制圖像到輸出設(shè)備的信息疟丙。
設(shè)備可以是PDF文件颖侄、bitmap或者顯示器的窗口。 CGContextRef 對應(yīng)繪畫者模式中的 Page享郊。
當(dāng)用 Quartz 繪圖時览祖,所有設(shè)備相關(guān)的特性都包含在Graphics Context 中。通過給Quartz 指定不同的 Graphics Context炊琉,就可將相同的圖像繪制到不同的設(shè)備上展蒂。
-
Quartz2D提供了以下幾種類型的Graphics Context:
- Bitmap Graphics Context
- PDF Graphics Context
- Window Graphics Context
- Layer Graphics Context(UI控件)重點(diǎn)
- Printer Graphics Context
1.4 繪圖路徑和內(nèi)存管理
1.4.1 繪制路徑
-
drawRect:(CGRect)rect
中的rect指的就是繪圖view的bounds
- (void)drawRect:(CGRect)rect {
//1.獲取圖形上下文對象
CGContextRef ctx = UIGraphicsGetCurrentContext();
//2.創(chuàng)建路徑
CGMutablePathRef pathM = CGPathCreateMutable();
//設(shè)置起點(diǎn)
CGPathMoveToPoint(pathM, NULL, 50, 50);
//加線
CGPathAddLineToPoint(pathM, NULL, 200, 200);
// 把路徑添加到圖形上下文中
CGContextAddPath(ctx, pathM);
//3.渲染
CGContextStrokePath(ctx);
//釋放內(nèi)存
// CGPathRelease(pathM);
CFRelease(pathM);
}
1.4.2 使用靜態(tài)分析工具
- 靜態(tài)分析工具的作用
- 不僅能夠檢測內(nèi)存泄漏的問題,還能檢測其他的問題.
- 這個工具僅僅是靜態(tài)的在分析內(nèi)存的問題,并不能真正的檢測內(nèi)存泄漏的問題.
1.4.3 使用Path 對象時的內(nèi)存管理問題
使用Path對象的時候,一定要注意內(nèi)存的問題,一定要注意內(nèi)存釋放玄货。
- 凡是遇到 retain 、 copy 悼泌、 create 出的對象, 都需要進(jìn)行 release
- 但是CGPathCreateMutable()不是 OC 方法, 所以不是調(diào)用 某個對象的 release方法
- CGXxxxxCreate 對應(yīng)的就有 CGXxxxxRelease松捉。
- 通過 CFRelease(任何類型)可以釋放任何類型。
- CFRelease屬于更底層的cocafoundation框架
- ARC僅僅是處理oc的引用計數(shù)的問題
2. 繪制基本圖形
好了馆里,坐好了隘世,老司機(jī)開始開車?yán)病?/p>
2.1 繪制三角形
- (void)drawRect:(CGRect)rect {
// 獲取context
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 創(chuàng)建起點(diǎn)
CGContextMoveToPoint(ctx, 10, 10);
// 創(chuàng)建兩條線段的終點(diǎn)
CGContextAddLineToPoint(ctx, 10, 90);
CGContextAddLineToPoint(ctx, 90, 90);
// 閉合path,讓他自動回到原點(diǎn)
CGContextClosePath(ctx);
// 執(zhí)行渲染
CGContextStrokePath(ctx);
}
2.2 繪制四邊形
- (void)drawRect:(CGRect)rect {
// Drawing code
// 獲取context對象
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 添加路徑
CGContextAddRect(ctx, CGRectMake(10, 10, 50, 50));
// 執(zhí)行渲染
CGContextStrokePath(ctx);
}
2.3 繪制橢圓鸠踪,也可以通過這種方式畫圓
- (void)drawRect:(CGRect)rect {
// 獲取context
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 添加橢圓丙者,通過矩形的方式。給出矩形的起點(diǎn)坐標(biāo)营密,長寬械媒,繪制一個內(nèi)切橢圓
CGContextAddEllipseInRect(ctx, CGRectMake(10, 10, 80, 50));
// 渲染
CGContextStrokePath(ctx);
}
2.4 繪制圓弧
- (void)drawRect:(CGRect)rect {
// 獲取context
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 繪制扇形。參數(shù):1+2评汰,圓點(diǎn)坐標(biāo)纷捞。參數(shù)3+4,起點(diǎn)和終點(diǎn)的弧度被去。參數(shù)5:0表示順時針主儡,1表示逆時針。
CGContextAddArc(ctx, 50, 50, 20, M_PI_4, M_PI, 1);
// 渲染
CGContextStrokePath(ctx);
}
2.5 畫扇形
- 先畫一個弧度惨缆,然后鏈接圓心糜值,最后關(guān)閉路徑就可以了。
- (void)drawRect:(CGRect)rect {
// 獲取context
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 繪制扇形坯墨。參數(shù):1+2寂汇,圓點(diǎn)坐標(biāo)。參數(shù)3+4捣染,起點(diǎn)和終點(diǎn)的弧度健无。參數(shù)5:0表示順時針,1表示逆時針液斜。
CGContextAddArc(ctx, 50, 50, 20, M_PI_4, M_PI, 1);
CGContextClosePath(ctx);
// 渲染
CGContextStrokePath(ctx);
}
2.6 畫線段
- (void)drawRect:(CGRect)rect {
// 獲取context對象
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 添加路徑:起點(diǎn)累贤、終點(diǎn)
CGContextMoveToPoint(ctx, 10, 10);
CGContextAddLineToPoint(ctx, 80, 80);
// 執(zhí)行渲染
CGContextStrokePath(ctx);
}
好了,下車~下一篇要更新一下Quartz2D的渲染模式少漆。