在調用drawRect:
方法之前,繪圖系統創建了一個圖形上下文CGContext
。上下文包括大量信息,比如畫筆顏色、文本顏色、當前字體、變形等。有時你可能想要修改上下文并使其恢復原樣。舉個例子,你現在有一個使用特定顏色繪制特定形狀的函數。由于只能有一只畫筆,因此在更改顏色后,就會影響調用函數的結果。為了避免這個副作用,你可以使用CGContextSaveGState
和CGContextRestoreGState
將上下文入棧和出棧。
??請不要與看起來相似的UIGraphicsPushContext
和UIGraphicsPopContext
混淆。它們做的并不是同一件事。CGContextSaveGState
記錄上下文的當前狀態。UIGraphicsPushContext
更改當前上下文。
??以下是CGContextSaveGState
的示例:
[[UIColor redColor] setStroke];
CGContextSaveGState(UIGraphicsGetCurrentContext());
[[UIColor blackColor] setStroke];
CGContextRestoreGState(UIGraphicsGetCurrentContext());
UIRectFill(CGRectMake(10, 10, 100, 100)); // 紅
這段代碼設置了畫筆的顏色為紅色并保存了上下文。之后它將把畫筆顏色改成黑色并恢復上下文。這樣當你繪圖的時候,畫筆又會變成紅色了。
??以下代碼展示了一個常見的錯誤:
[[UIColor redColor] setStroke];
//下一行不對
UIGraphicsPushContext(UIGraphicsGetCurrentContext());
[[UIColor blackColor] setStroke];
UIGraphicsPopContext();
UIRectFill(CGRectMake(10, 10, 100, 100)); //黑
在這個示例中,畫筆顏色設置為了紅色,并且上下文切換為當前毫無用處的上下文。然后更改畫筆的顏色為黑色,接著通過出棧使上下文回到原始狀態(實際上等于什么都沒做)。現在將會畫一個黑色的矩形,這絕對不是你想要的。
??使用UIGraphicsPushContext
并不能保存上下文的當前狀態(畫筆顏色、線條寬度等),而是完全切換上下文。假設你正在當前視圖上下文中繪制什么東西,這時想要在位圖上下文中繪制完全不同的東西。如果要使用UIKit
來進行任意繪圖,你會希望保存當前的UIKit
上下文,包括所有已經繪制的內容,接著切換到一個全新的繪圖上下文中。這就是UIGraphicsPushContext
的功能。創建完位圖后,再將你的舊上下文出棧。而這就是UIGraphicsPopContext
的功能。