2012-04-12 93 views
0

似乎有一點問題試圖將我的視圖繪製到上下文中。drawRect:/ renderInContext:問題

我的基本設置是,我有一個視圖控制器,擁有一個UIPageViewController,其中我加載控制器的視圖可以由用戶的手指繪製。基本上,我有一本書,可以。

頁面時我在書裏保存圖像調用

- (UIImage *)wholeImage { 
    // Render the layer into an image and return 
    UIGraphicsBeginImageContext(self.bounds.size); 
    [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *wholePageImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return wholePageImage; 
} 

這樣做的返回值然後被保存到一個文件打開繪製。然而,當我把這種節約方法,那麼第

[self.layer renderInContext:UIGraphicsGetCurrentContext()]; 

被擊中,這似乎讓我drawRect:方法,該方法如下重寫一個電話,

- (void)drawRect:(CGRect)rect { 
    // Draw the current state of the image 
    [self.currentImage drawAtPoint:CGPointMake(0.0f, 0.0f)]; 
    CGPoint midPoint1 = [self midPointOfPoint1:previousPoint1 point2:previousPoint2]; 
    CGPoint midPoint2 = [self midPointOfPoint1:currentPoint point2:previousPoint1]; 

    // Get the context 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // Add the new bit of line to the image 
    [self.layer renderInContext:context]; 
    CGContextMoveToPoint(context, midPoint1.x, midPoint1.y); 
    CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, midPoint2.x, midPoint2.y); 
    CGContextSetLineCap(context, kCGLineCapRound); 
    CGContextSetLineWidth(context, self.lineWidth); 
    if (self.drawMode == LNDrawViewDrawModeTipex) CGContextSetBlendMode(context, kCGBlendModeClear); 
    else CGContextSetBlendMode(context, kCGBlendModeCopy); 
    CGContextSetStrokeColorWithColor(context, self.lineColour.CGColor); 
    CGContextStrokePath(context); 

    // Call super 
    [super drawRect:rect]; 
} 

這是有道理的,但它似乎得到遞歸調用,直到最後我在一個完全喪失得到一個EXC_BAD_ACCESS在這條線

[self.currentImage drawAtPoint:CGPointMake(0.0f, 0.0f)]; 

上午至於是什麼原因造成這種並一直推動我堅果。

如果有幫助,我的調用堆棧開始這樣

enter image description here

,然後遞歸地繼續,直至最後與

enter image description here

會很感激結束,並幫助和見解任何人都可以給!

編輯:(感動加潤色)

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    // Get the touch 
    UITouch *touch = [touches anyObject]; 

    // Get the points 
    previousPoint2 = previousPoint1; 
    previousPoint1 = [touch previousLocationInView:self]; 
    currentPoint = [touch locationInView:self]; 

    // Calculate mid point 
    CGPoint mid1 = [self midPointOfPoint1:previousPoint1 point2:previousPoint2]; 
    CGPoint mid2 = [self midPointOfPoint1:currentPoint point2:previousPoint1]; 

    // Create a path for the last few points 
    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathMoveToPoint(path, NULL, mid1.x, mid1.y); 
    CGPathAddQuadCurveToPoint(path, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); 
    CGRect pathBounds = CGPathGetBoundingBox(path); 
    CGPathRelease(path); 

    // Take account of line width 
    pathBounds.origin.x -= self.lineWidth * 2.0f; 
    pathBounds.origin.y -= self.lineWidth * 2.0f; 
    pathBounds.size.width += self.lineWidth * 4.0f; 
    pathBounds.size.height += self.lineWidth * 4.0f; 

    UIGraphicsBeginImageContext(pathBounds.size); 
    [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    self.currentImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    [self setNeedsDisplayInRect:pathBounds];  

}

回答

0

你不能調用[self.layer renderInContext:]drawRect:,期。如你所知,renderInContext:調用drawRect:如果它被實現,這將導致無限遞歸。

您應該單獨渲染一本書,然後使用渲染的圖像讓用戶在其上繪製。一種方法是將自包含的繪圖代碼放在UIGraphicsBeginImageContext()/UIGraphicsEndImageContext()塊中,並使用drawRect:中的結果圖像。另一種方法是使用兩個不是彼此的子視圖的不同視圖,其中一個繪製未改變的書,另一個繪製用戶草圖。

編輯:首先,你需要一個原始圖像(書頁,無論)。將其繪製在UIGraphicsBeginImageContext()/UIGraphicsEndImageContext()區塊內,而不需要致電[self.layer renderInContext:],並將其保存在視圖的伊維爾(例如,self.currentImage)中。在touchesMoved:withEvent:呼叫setNeedsDisplay(它會爲你打電話drawRect:)更新視圖。作爲背景圖片,使用self.currentImagedrawRect:

我希望我不太模糊。

+0

嗨,謝謝你的回覆。不要以爲我完全確定你的意思。剛剛添加我的觸動代碼移動到問題。我在UIGraphicsBeginImageContext()/ UIGraphicsEndImageContext()塊中做了一些繪製代碼,但是除非我在drawRect中再次調用renderInContext,我似乎會得到一些相當的集市行爲..? – 2012-04-12 18:24:39

+0

似乎drawRect並不總是從renderInContext被調用,因爲我似乎可以在沒有這個問題的情況下在我的視圖上畫好......!?我很困惑。 – 2012-04-12 18:28:40

+0

我認爲你的架構有點不對。基本上,你需要做兩件不相關的事情:繪製圖像並在其上繪製一些東西。由於它們是獨立的,因此得出最終結果的視圖應該將原始/背景圖像放在其他地方,而不是從其內容中獲取。 'drawRect:'的結果被設置爲視圖圖層的內容。 'renderInContext:'每次都可能或不可以調用'drawRect:',這取決於你控制之外的許多因素。它可以使用緩存的圖像,但它是一個實現細節。 – Costique 2012-04-12 18:40:31