2012-12-24 76 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