CGContextSaveGState与UIGraphicsP
在调用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
的功能。