`
1021082712
  • 浏览: 86794 次
  • 性别: Icon_minigender_2
  • 来自: 武汉
社区版块
存档分类
最新评论

CGContextSaveGState与UIGraphicsPushContext

    博客分类:
  • ios
阅读更多

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    // do drawing here
    CGContextRestoreGState(context);

}

 

 

- (void)drawRect:(CGRect)rect 
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    UIGraphicsPushContext(context);
    // do drawing here
    UIGraphicsPopContext(); 
}

 

Questions: What is the difference between those methods? Which one is better to use? Are there some examples of proving one method better than other and vise versa?

 

Answer:UIGraphicsPushContext(context) pushes context onto a stack of CGContextRefs (making context the current drawing context), whereas CGContextSaveGState(context) pushes the current graphics state onto the stack of graphics states maintained by context. You should use UIGraphicsPushContext if you need to make a new CGContextRef the current drawing context, and you should use CGContextSaveGState when you're working with one graphics context and just want to save, for example: the current transform state, fill or stroke colors, etc.

 

 

 

在调用drawRect:方法之前,绘图系统创建了一个图形上下文(CGContext)。上下文包括大量信息,比如画笔颜色、文本颜色、当前字体、变形等。有时你可能想要修改上下文并使其恢复原样。举个例子,你现在有一个使用特定颜色绘制特定形状的函数。由于只能有一只画笔,因此在更改颜色后,就会影响调用函数的结果。为了避免这个副作用,你可以使用CGContextSaveGStateCGContextRestoreGState将上下文入栈和出栈。
请不要与看起来相似的UIGraphicsPushContextUIGraphicsPopContext混淆。它们做的并不是同一件事。CGContextSaveGState记录上下文的当前状态。UIGraphicsPushContext更改当前上下文。以下是CGContextSaveGState的示例。
1
2
3
4
5
    [[UIColor redColor] setStroke];
    CGContextSaveGState(UIGraphicsGetCurrentContext());
    [[UIColor blackColor] setStroke];
    CGContextRestoreGState(UIGraphicsGetCurrentContext());
    UIRectFill(CGRectMake(10, 10, 100, 100)); // 红
这段代码设置了画笔的颜色为红色并保存了上下文。之后它将把画笔颜色改成黑色并恢复上下文。这样当你绘图的时候,画笔又会变成红色了。
以下代码展示了一个常见的错误。
1
2
3
4
5
6
    [[UIColor redColor] setStroke];
    //下一行不对
    UIGraphicsPushContext(UIGraphicsGetCurrentContext());
    [[UIColor blackColor] setStroke];
    UIGraphicsPopContext();
    UIRectFill(CGRectMake(10, 10, 100, 100)); //
在这个示例中,画笔颜色设置为了红色,并且上下文切换为当前毫无用处的上下文。然后更改画笔的颜色为黑色,接着通过出栈使上下文回到原始状态(实际上等于什么都没做)。现在将会画一个黑色的矩形,这绝对不是你想要的。
使用UIGraphicsPushContext并不能保存上下文的当前**状态**(画笔颜色、线条宽度等),而是完全切换上下文。假设你正在当前视图上下文中绘制什么东西,这时想要在位图上下文中绘制完全不同的东西。如果要使用UIKit来进行任意绘图,你会希望保存当前的UIKit上下文,包括所有已经绘制的内容,接着切换到一个全新的绘图上下文中。这就是UIGraphicsPushContext的功能。创建完位图后,再将你的旧上下文出栈。而这就是UIGraphicsPopContext的功能。这种情况只会在要使用UIKit在新的位图上下文中绘图时才会发生。只要你使用的是Core Graphics函数,就不需要去执行上下文入栈和出栈,因为Core Graphics函数将上下文视作参数。
这是极其有用的常见操作。因为其常用性,苹果公司为其创建了一个叫做UIGraphicsBeginImageContext的快捷方式。它负责将旧的上下文入栈、为新上下文分配内存、创建新的上下文、翻转坐标系统,并使其作为当前上下文使用。它替你完成了大部分的工作。
分享到:
评论

相关推荐

    ios上的图片处理与动画代码

    5. 层次与混合模式:理解`CGContextSetBlendMode`和`CGContextSaveGState/CGContextRestoreGState`来控制绘图的透明度和混合效果。 Core Animation是iOS中实现流畅动画的关键技术,它是基于图层(CALayer)的动画...

    图形上下文栈Demo

    3. **上下文的堆叠与切换**:在绘图过程中,可以多次调用`CGContextSaveGState`和`CGContextRestoreGState`,形成一个图形上下文的栈。这样可以在多个绘图任务间自由切换,而不会影响其他任务的绘图设置。 4. **...

    Quartz2D使用案例

    图层在Quartz2D中扮演着重要角色,通过`CGContextSaveGState`和`CGContextRestoreGState`可以保存和恢复当前的绘图状态,以便于进行图层操作。变换如旋转、缩放和位移可以通过`CGContextTranslateCTM`、`...

    drawrect中实现橡皮擦功能(非背景色填充)

    6. **保存与恢复上下文状态**:为了防止对其他绘图操作产生影响,记得在修改`CGContext`状态前保存状态(`CGContextSaveGState`),并在完成橡皮擦操作后恢复状态(`CGContextRestoreGState`)。 7. **处理橡皮擦...

    iOS 中pdf文件的绘制

    CGContextSaveGState(context!) CGContextTranslateCTM(context!, 0, bounds.height) CGContextScaleCTM(context!, 1.0, -1.0) CGContextDrawPDFPage(context!, firstPage!) CGContextRestoreGState(context!) ...

    ios-图片添加贴纸.zip

    这个过程可能需要使用到CGContextSaveGState和CGContextRestoreGState来保存和恢复绘图状态,以及CGAffineTransformMakeTranslation、CGAffineTransformMakeRotation和CGAffineTransformScale等函数来实现贴纸的平移...

    IOS应用源码之图片倒影效果 .rar

    8. **保存和恢复上下文状态**:在进行复杂的图形操作时,使用`CGContextSaveGState`和`CGContextRestoreGState`可以保存和恢复图形上下文的状态,避免对后续绘制造成影响。 9. **内存管理**:在iOS开发中,需要注意...

    quartz2D

    8. **Core Graphics与UIKit的关系**: 在iOS中,Quartz 2D是Core Graphics框架的一部分,与UIKit框架协同工作。UIKit提供了更高层次的UI组件和视图,但底层仍依赖Quartz 2D进行渲染。开发者可以在UIView的`drawRect:`...

    iOS Quartz2D详解 - imlifengfeng1

    5. 最后,为了保持绘图状态的整洁,我们可能需要使用`CGContextSaveGState`和`CGContextRestoreGState`来保存和恢复图形上下文的状态。这两个函数允许我们在不干扰其他绘图操作的情况下进行局部更改。 举个简单的...

    ios 文字跑马灯效果实现

    一、核心概念与原理 1. Core Graphics:iOS中的Core Graphics框架提供了一组低级别的图形绘制API,可以用来进行2D图形的绘制,包括线条、形状、文本等。在实现跑马灯效果时,我们需要利用这个框架来绘制并动态更新...

    Quartz2D渐变demo

    一旦创建完成,可以使用`CGContextSaveGState`和`CGContextRestoreGState`来保存和恢复绘图上下文的状态,防止渐变影响其他绘图操作。之后,使用`CGContextClipToRect`限定渐变的绘制区域,最后调用相应的绘制函数...

    ios应用源码之图片倒影效果 2018127

    4. 使用渐变层(CAGradientLayer)在倒影与背景之间创建平滑的过渡。渐变层从完全不透明到完全透明,使得倒影在底部逐渐消失。 5. 从位图上下文中获取新的CGImage,这将是包含原始图片和倒影的新图像。 6. 最后,将...

    ios 绘图以及重绘

    - `CGContextSaveGState`:保存当前的绘图状态。 - `CGContextRestoreGState`:恢复之前保存的绘图状态。 在复杂的绘图场景中,经常需要多次更改绘图环境(如颜色、线条宽度等),这时就需要用到保存和恢复状态的...

    IOS开发 读取PDF文件

    此外,我们还会使用Core Graphics框架,它与Quartz 2D紧密关联,提供了低级别的图形操作接口。 以下是实现这一功能的关键步骤: 1. **导入必要的框架**: 在你的Swift文件顶部,你需要导入UIKit和CoreGraphics...

    CGContext 小记

    当需要暂时改变这些属性时,可以调用`CGContextSaveGState`保存当前状态,之后再调用`CGContextRestoreGState`恢复之前的状态,这在需要多次重复相同绘制操作但中间又有不同设置时非常有用。 在实际开发中,...

    简单的绘图实现

    - 也可以考虑使用`CGContextSaveGState`和`CGContextRestoreGState`来保存和恢复绘图状态,以便在多个操作之间保持一致性。 5. **优化性能**: - 避免在`drawRect:`中进行复杂的计算或频繁调用,因为这会导致重绘...

    Cocoa绘制渐进色文字

    使用`CGContextSaveGState`保存当前图形上下文的状态,以便在绘制结束后恢复。然后根据渐变的方向设置CGContext的透明度层,并设置渐变的起点和终点。 4. **遍历文字并绘制** 对于每个字符,我们需要计算其在文本...

    深入理解iPhone屏幕双缓冲技术

    此外,为了确保绘图过程的流畅性,通常还会结合使用`CGContextSaveGState`和`CGContextRestoreGState`函数来保存和恢复绘图状态,以及`CGContextSetRGBFillColor`、`CGContextFillRect`和`CGContextStrokePath`等...

    ios弹幕高效加载实现方式实例代码

    为了防止背景被裁剪,使用`CGContextSaveGState`和`CGContextRestoreGState`保存和恢复上下文状态,使得背景能在未裁剪的画板上绘制。 4. **动态滚动管理**: 弹幕的滚动是通过定时器实现的。定时器定期更新每个弹...

    Douraeman:Quartz2D画的一个哆啦A梦头像

    8. **状态保存与恢复(State Saving and Restoring)**:在进行复杂绘图时,开发者可能会使用`CGContextSaveGState`和`CGContextRestoreGState`来保存和恢复当前绘图状态,以避免影响后续的绘图操作。 项目中的...

Global site tag (gtag.js) - Google Analytics