2012-12-24 70 views
1

我实际上试图在视图上绘制线条。为了在每次抽签之前不清楚背景,我明白我必须创建自己的背景以便利用它。在自定义上下文中绘制

我发现这个方法来创建上下文:

CGContextRef MyCreateBitmapContext (int pixelsWide, 
           int pixelsHigh) 
{ 
    CGContextRef context = NULL; 
    CGColorSpaceRef colorSpace; 
    void *   bitmapData; 
    int    bitmapByteCount; 
    int    bitmapBytesPerRow; 

    bitmapBytesPerRow = (pixelsWide * 4); 
    bitmapByteCount  = (bitmapBytesPerRow * pixelsHigh); 

    colorSpace = CGColorSpaceCreateDeviceRGB(); 
    bitmapData = calloc(bitmapByteCount, sizeof(int)); 
    if (bitmapData == NULL) 
    { 
     fprintf (stderr, "Memory not allocated!"); 
     return NULL; 
    } 
    context = CGBitmapContextCreate (bitmapData, 
            pixelsWide, 
            pixelsHigh, 
            8,  // bits per component 
            bitmapBytesPerRow, 
            colorSpace, 
            kCGImageAlphaPremultipliedLast); 
    if (context== NULL) 
    { 
     free (bitmapData); 
     fprintf (stderr, "Context not created!"); 
     return NULL; 
    } 
    CGColorSpaceRelease(colorSpace); 

    return context; 
} 

但我的问题是:我该如何使用这一背景下,以没有我的观点清洗每一次?

编辑(@Peter Hosey的答案后)

我试着这样做:

- (void)drawRect:(CGRect)rect { 
    // Creation of the custom context 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGImageRef cgImage = CGBitmapContextCreateImage(context); 
    CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), cgImage); 
    CGImageRelease(cgImage); 
    if (isAuthorizeDrawing) { 
     [self drawInContext:context andRect:rect]; // Method which draw all the lines sent by the server 
     isAuthorizeDrawing = NO; 
    } 

    // Draw the line 
    [currentDrawing stroke]; 
} 

我还设置clearsContextBeforeDrawing为NO UIView的。

当我缩放(isAuthorizeDrawing设置为YES,以便重新绘制正确缩放的所有线条)时,线条不会消失,但是当我尝试绘制新线条时(isAuthorizeDrawing设置为NO以便不重绘所有内容在每个setNeedsDisplay调用),所有的行消失,并且绘图将非常缓慢..:/

我做错了什么?

EDIT 2

这里是我的绘画方法:

-(void)drawInContext:(CGContextRef)context { 
    for (int i = 0; i < self.drawings.count; ++i) { 
     Drawing* drawing = [self.drawings objectAtIndex:i]; 

     CGContextSetStrokeColorWithColor(context, drawing.colorTrait.CGColor); 
     CGContextSetLineWidth(context, 1.0); 

     CGContextMoveToPoint(context, [[drawing.points objectAtIndex:0] CGPointValue].x * self.zoomScale, [[drawing.points objectAtIndex:] CGPointValue].y * self.zoomScale); 

     for (int i = 1; i < drawing.points.count; i++) { 
      CGContextAddLineToPoint(context, [[drawing.points objectAtIndex:i] CGPointValue].x * self.zoomScale, [[drawing.points objectAtIndex:i] CGPointValue].y * self.zoomScale); 
     } 

     CGContextStrokePath(context); 
    } 
} 

-(void)drawRect:(CGRect)rect { 
    if (isRedrawing) { 
     [self drawInContext:UIGraphicsGetCurrentContext()]; 
     isRedrawing = NO; 
    } 

    [[UIColor redColor] set]; 
    [currentPath stroke]; 
} 

回答

4

你的上下文保存到你所有的为你绘制的。

当您绘制到视图提供的上下文中时(即在drawRect:内),视图每次都会创建一个新的上下文,或者它已经擦除了上下文的内容,比如摇动Etch-a-Sketch。无论哪种方式,你都会得到一个上下文(至少有效),没有任何东西被绘制。

当你正在绘制你的上下文时,假设你没有做任何事情来清除它在使用之间的任何东西,那么你绘制的所有东西都会堆积起来。

这样做的一个分支是,您需要小心绘制状态,如当前转换矩阵,剪切路径等,因为在绘制会话之间没有重置这些参数。这可能是有用的,取决于你在做什么,但无论哪种方式,你都需要了解它并做相应的规划。

大概你想向用户展示你迄今为止所画的东西(即当drawRect:发生时)。为此,ask the bitmap context to create an image of its contentsdraw that image分成the current (UIKit-supplied) context

另外,只是tell the view not to clear itself before every draw,并且根本不管理自己的位图上下文。

+0

我用第一段代码编辑了我的问题,但出了什么问题,你能帮我吗? – Seb

+0

@Seb:您将上下文的内容捕获到图像,然后将该图像回到相同的上下文。至多,这将会给所有的事情带来双重打击,我不认为这是你想要的。假设您只想将新东西添加到您已绘制的内容中,则不需要从上下文创建图像。过去的绘图已经在那里(CreateImage如何捕获它)。 –

+0

我不确定要完全理解。没有必要在上下文中绘制当前上下文的图像,好的。那么,我需要做什么? 我希望找到一个解决方案,我不需要重绘所有东西(所以不要在每次setNeedsDisplay调用时调用[self drawInContext:context andRect:rect])。 – Seb