我试图保存和恢复一个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);
}发布于 2009-09-18 22:24:37
我认为你可能误解了CGContextSaveGState()和CGContextRestoreGState()的功能。它们将当前图形状态推送到堆栈上并将其弹出,允许您转换当前绘图空间、更改线条样式等,然后将状态恢复到设置这些值之前的状态。它不存储绘图元素,如路径。
从documentation on CGContextSaveGState()
每个图形上下文维护图形状态的堆栈。请注意,并非当前绘图环境的所有方面都是图形状态的元素。例如,当前路径不被视为图形状态的一部分,因此在调用
CGContextSaveGState()函数时不会保存。
图形状态堆栈应该在drawRect:开始时重置,这就是为什么当您尝试从堆栈中弹出图形状态时出现错误的原因。因为你没有推一个,所以没有一个可以弹出来。所有这些都意味着,您不能将绘图作为图形状态存储在堆栈上,然后再将其恢复。
如果您所担心的只是缓存您的绘图,那么这是由支持您的UIView的CALayer (在iPhone上)为您完成的。如果你所做的只是移动你的视图,它不会被重绘。只有当您手动告诉它这样做时,它才会被绘制。如果您确实需要更新绘图的一部分,我建议将静态元素拆分到它们自己的视图或CALayers中,以便只重绘更改的部分。
发布于 2009-09-18 19:46:05
您不想先保存再恢复吗?如果在保存之前进行恢复,则没有要恢复的上下文,并且会出现下溢。
下面是我使用它的方式:
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);或者:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextAddRect(context, originalRect);
CGContextClip(context);
[self drawInRect:rect];
CGContextRestoreGState(context);也许你正在尝试做其他的事情。
发布于 2013-10-28 06:05:12
。。根据您的代码!,您似乎是在保存之前恢复上下文。首先要做的是:
为每个规则创建上下文并保存其状态,又名push context
Pop
Pop
Store(push) there be context
CGCreate,CGCopy,<代码>H217<代码>G218的上下文示例代码:
[super drawRect:rect];
CGContextRef ctx = UIGraphicsGetCurrentContext();
// save context
CGContextSaveGState(ctx);
// do some stuff
CGContextSetRGBStrokeColor(ctx, 1.0, 0.5, 0.5, 1.0);
// drawing vertical lines
CGContextSetLineWidth(ctx, 1.0);
for (int i = 0; i < [columns count]; i++) {
CGFloat f = [((NSNumber*) [columns objectAtIndex:i]) floatValue];
CGContextMoveToPoint(ctx, f+(i*20.5), 0.5);
CGContextAddLineToPoint(ctx, f+(i*20.5), self.bounds.size.height);
}
// restore context
CGContextRestoreGState(ctx);
// do some other stuff
// drawing hozizontal lines
CGContextSetLineWidth(ctx, 1.0);
CGContextSetRGBStrokeColor(ctx, 0.12385, 0.43253, 0.51345, 1.0);
for (int i = 0; i < [columns count]; i++) {
CGFloat f = [((NSNumber*) [columns objectAtIndex:i]) floatValue];
CGContextMoveToPoint(ctx, 0.5, f+(i*20.5));
CGContextAddLineToPoint(ctx,self.bounds.size.width,f+(i*20.5));
}
CGContextStrokePath(ctx);
}
// No context CGContextRelease , since we never used CGContextCreate https://stackoverflow.com/questions/1446446
复制相似问题