保存和恢复CGContext

coc*_*her 9 iphone core-graphics quartz-graphics cgcontext

我正在尝试保存和恢复CGContext以避免第二次进行繁重的绘图计算而我收到了错误<Error>: CGGStackRestore: gstack underflow.

我究竟做错了什么?这样做的正确方法是什么?

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    if (initialized) {
        CGContextRestoreGState(context);
        //scale context
        return;
    }

    initialized = YES;

    //heavy drawing computation and drawing

    CGContextSaveGState(context);
}
Run Code Online (Sandbox Code Playgroud)

Bra*_*son 18

我想你可能会错误地解释什么CGContextSaveGState()CGContextRestoreGState()做什么.它们将当前图形状态推送到堆栈并将其弹出,让您转换当前绘图空间,更改线条样式等,然后将状态恢复为设置这些值之前的状态.它不存储绘图元素,如路径.

CGContextSaveGState()文档:

每个图形上下文都维护着一堆图形状态.请注意,并非当前绘图环境的所有方面都是图形状态的元素.例如,当前路径不被视为图形状态的一部分,因此在调用CGContextSaveGState()函数时不会保存 .

应该在开始时重置图形状态堆栈drawRect:,这就是当您尝试从堆栈中弹出图形状态时出现错误的原因.既然你没有按过一个,就没有一个可以弹出.所有这些意味着您无法将图形作为图形状态存储在堆栈中,然后再将其还原.

如果你担心的只是缓存你的绘图,那就是CALayer那个支持你UIView(在iPhone上).如果你正在做的只是移动你的视图,它将不会被重绘.只有手动告诉它才能绘制它.如果您必须更新部分图形,我建议将静态元素拆分为自己的视图,或者CALayers只重绘更改的部分.


mah*_*udz 7

你不想先保存然后恢复吗?如果要在保存之前进行恢复,则没有要恢复的上下文,并且您将获得下溢.

这是我使用它的方式:

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextClipToRect(context, CGRectMake(stripe[i][8], stripe[i][9], stripe[i][10], stripe[i][11]));
CGContextDrawLinearGradient(context, gradient, CGPointMake(15, 5), CGPointMake(15, 25), 0);
CGContextRestoreGState(context);
Run Code Online (Sandbox Code Playgroud)

要么:

  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextSaveGState(context);
  CGContextAddRect(context, originalRect);
  CGContextClip(context);

  [self drawInRect:rect];

  CGContextRestoreGState(context);
Run Code Online (Sandbox Code Playgroud)

也许你正在尝试做别的事情.