Core Graphics用於處理本地2D向量渲染和圖片渲染。其中滿是名稱相近,讓人郁悶的C接口。
對於在iOS上編程有一段時間的人來說有別的方法也會盡量避免使用這些C函數。
畢竟直接用xCode已有控件的話,只要拖一拖,然后少許的代碼就可以做出某些效果,何必
自找苦吃?!但是Core Graphics有一個很大的優點:快! ps,我不是說要重復找輪子。
繪制在drawRect:方法中進行
當一個View需要繪制的時候,drawRect:方法會被調用。在這個方法中Core Graphics就會發揮作用,
你指定的區域會被重新繪制。但是你沒法直接繪制UIView,而是繼承UIView並自己實現drawRect:這個方法來進行繪制。
找到繪制的上下文
在繪制先需要保證繪制所在的上下文是在當前的View中。當前上下文使用UIGraphicsGetCurrentContext獲得。
對於當前上下文,可以理解為Core Graphics對於當前所操作View的繪制操作一個指針,跟蹤了全部的繪制操作。在C庫中很多。
相當於面向對象編程語言中一個類的self指針。示例:
2 CGContextRef ctx = UIGraphicsGetCurrentContext();
3 // 繪制操作
4 }
在之后的代碼里就可以用ctx來表示當前上下文。
繪制
繪制UIImage可以非常的簡單,如:
2 CGContextRef ctx = UIGraphicsGetCurrentContext();
3 UIImage *img = [UIImage imageNamed: @" MyImage.png "];
4 [img drawInRect:rect];
5 }
畫線
用Core Graphics畫線和平時用筆畫線的邏輯是一樣的。先找到起始點,放下畫筆,然后給畫筆一系列的指令告訴它之后
往哪里畫。每往下畫一段都以上一段的終點為起點。用函數CGContextMoveToPoint把畫筆移動到起始點。然后用函數
CGContextAddLineToPoint指定線條的終點,並在這兩點之間畫線。其他,還可以指定線條的顏色等。下面用具體的代碼
來說明。代碼:
2 {
3 // 獲取當前繪圖上下文
4 CGContextRef con = UIGraphicsGetCurrentContext();
5
6 // 繪制箭桿部分
7 CGContextMoveToPoint(con, 100, 100);
8 CGContextAddLineToPoint(con, 100, 25);
9 CGContextSetLineWidth(con, 20);
10 CGContextStrokePath(con);
11
12 // 繪制箭頭部分
13 CGContextSetFillColorWithColor(con, [[UIColor redColor] CGColor]);
14 CGContextMoveToPoint(con, 80, 25);
15 CGContextAddLineToPoint(con, 100, 0);
16 CGContextAddLineToPoint(con, 120, 25);
17 CGContextFillPath(con);
18 }
最后結果,如圖:
繪制長方形
繪制是用CGRect變量指定位置和長,寬值。然后把該變量作為參數傳給函數CGContextAddRect
2
3 CGContextRef context = UIGraphicsGetCurrentContext();
4
5 CGContextSetLineWidth(context, 2.0);
6
7 CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
8
9 CGRect rectangle = CGRectMake( 60, 170, 200, 80);
10
11 CGContextAddRect(context, rectangle);
12
13 CGContextStrokePath(context);
14 }
效果如下:
繪制上下文狀態保存
從上面繪制的例子中可以看出。即使只是簡單的畫一條線也需要調好幾個函數來設置這條線的
顏色、寬度,沿着哪條路徑繪制等屬性。 Core Graphics會保存這些屬性在其內部的棧中。這個繪制狀態就好比是一直筆,
你可以換筆頭,顏色來畫出不同的效果。但是如果你忘記把所有的東西換回去,那么下次再畫出來的效果難保不會出乎意料。
函數CGContextSaveGState和函數CGContextRestoreGState專門用來處理繪制狀態。CGContextSaveGState函數
就相當於給你當前的繪制狀態打了個書簽,之后你可以任意修改你想要修改的屬性。然后可以用函數CGContextRestoreGState來重置繪制狀態,
回到打了書簽的地方。這兩個函數必須要配對使用! 否則的話,繪制狀態就全部亂了,要不繪出來的不是你想要,要不繪制都無法繼續。
2 {
3 CGContextRef ctx = UIGraphicsGetCurrentContext();
4
5 // 設置屬性
6 CGColorRef whiteColor = [UIColor whiteColor].CGColor;
7 CGColorRef lightColor = _lightColor.CGColor;
8 CGColorRef darkColor = _darkColor.CGColor;
9 CGColorRef shadowColor = [UIColor colorWithRed:.2f green:.2f blue:.2f alpha:.5f].CGColor;
10
11 CGContextSetFillColorWithColor(ctx, whiteColor);
12 CGContextFillRect(ctx, _paperRect);
13
14 // 保存繪制屬性
15 CGContextSaveGState(ctx);
16
17 // 繪制。。。
18
19 // 還原繪制屬性
20 CGContextRestoreGState(ctx);
21 }
View的重繪
蘋果文檔的一段話說的非常清楚:
任何時候,當視圖的一部分需要重畫時,UIView對象內置的描畫代碼就會調用其drawRect:方法,並向它傳入一個包含需要重畫的視圖區域的矩形。您需要在定制視圖子類中重載這個方法,並在這個方法中描畫視圖的內容。在首次描畫視圖時,UIView傳遞給drawRect:方法的矩形包含視圖的全部可見區域。但在隨后的調用中,該矩形只代表實際需要被描畫的部分。觸發視圖更新的動作有如下幾種:
對遮擋您的視圖的其它視圖進行移動或刪除操作。
將視圖滾出屏幕,然后再重新回到屏幕上。
顯式調用視圖的
setNeedsDisplay或者setNeedsDisplayInRect:方法。
在調用drawRect:方法之后,視圖會將自己標志為已更新,然后等待新的更新動作觸發下一個更新周期。如果您的視圖顯示的是靜態內容,則只需要在視圖的可見性發生變化時進行響應就可以了,這種變化可能由滾動或其它視圖是否被顯示引起的。然而,如果您需要周期性地更新視圖內容,就必須確定什么時候調用setNeedsDisplay或setNeedsDisplayInRect:方法來觸發更新。舉例來說,如果您需要每秒數次地更新內容,則可能要使用一個定時器。在響應用戶交互或生成新的視圖內容時,也可能需要更新視圖。
最后,暫時先總結這么多,后面會陸續深入講解這部分內容。只要參考着蘋果的官方文檔多練。在實際開發中多用。你自然會對Core Graphics駕輕就熟。
希望此文對你有所幫助。謝謝!
