18

我原来的问题:

我正在创建一个简单的绘图应用程序,并且需要能够在我的drawRect. 在不完全替换现有内容的情况下绘制现有内容的正确方法是什么?

根据在这里和其他地方收到的答案,这就是交易。

  1. 您应该准备好在drawRect 调用时重新绘制整个矩形。

  2. 无法通过执行以下操作来防止内容被删除:

    [self setClearsContextBeforeDrawing: NO];

    这只是对图形引擎的一个提示,让它为您预先清除视图是没有意义的,因为无论如何您可能需要重新绘制整个区域。它可能会阻止您的视图被自动删除,但您不能依赖它

  3. 要在视图顶部绘制而不擦除,请在屏幕外位图上下文中进行绘图(系统永远不会清除该上下文。)然后在您的 中drawRect,从该屏幕外缓冲区复制到视图。

例子:

- (id) initWithCoder: (NSCoder*) coder {    
     if (self = [super initWithCoder: coder]) {
         self.backgroundColor = [UIColor clearColor];
         CGSize size = self.frame.size;
         drawingContext = [self createDrawingBufferContext: size];
     }

     return self;
 }

- (CGContextRef) createOffscreenContext: (CGSize) size  {
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, size.width*4, colorSpace, kCGImageAlphaPremultipliedLast);
    CGColorSpaceRelease(colorSpace);

    CGContextTranslateCTM(context, 0, size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    return context;
}


- (void)drawRect:(CGRect) rect {    
    UIGraphicsPushContext(drawingContext);
    CGImageRef cgImage = CGBitmapContextCreateImage(drawingContext); 
    UIImage *uiImage = [[UIImage alloc] initWithCGImage:cgImage];
    UIGraphicsPopContext();
    CGImageRelease(cgImage);
    [uiImage drawInRect: rect];
    [uiImage release];
 }

TODO:任何人都可以优化,drawRect以便只使用(通常很小的)修改后的矩形区域进行复制吗?

4

4 回答 4

5

在离屏图像中绘制所有内容是相当常见的,并且在绘制屏幕时简单地显示该图像。您可以阅读:创建位图图形上下文

于 2009-05-14T20:46:11.790 回答
1

关于优化drawRect

试试这个:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGImageRef cgImage = CGBitmapContextCreateImage(drawingContext);
    CGContextClipToRect(context, rect);
    CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), cgImage);
    CGImageRelease(cgImage);
}

之后,您还应该在代码中注释这些行:

//CGContextTranslateCTM(context, 0, size.height);
//CGContextScaleCTM(context, 1.0, -1.0);

还创建了一个单独的问题,以确保它是最佳方式。

于 2010-06-14T22:58:35.640 回答
0

这似乎是比我一直使用的更好的方法。也就是说,在触摸事件中,我制作了即将更新的视图的副本。然后在 drawRect 中,我获取该图像并将其绘制到视图并同时更改我的其他视图。

但这似乎效率低下,但我想出了如何做到这一点的唯一方法。

于 2009-11-14T20:38:14.110 回答
0

这可以防止您的视图在 drawRect 完成之前被删除:

[self.layer setNeedsDisplay];

此外,我发现最好在 drawRect 方法中完成所有绘图(除非你有充分的理由不这样做)。在屏幕外绘制和传输需要更多时间并增加更多复杂性,然后简单地绘制一次。

于 2012-07-12T09:42:21.367 回答