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]; } 

这是有道理的,但似乎recursion调用,直到最后我得到这一行EXC_BAD_ACCESS

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

我完全不知道是什么原因导致了这一切,并一直在推动我的坚果。

如果有帮助,我的调用堆栈就像这样开始

在这里输入图像说明

然后recursion地继续下去,直到它终于结束

在这里输入图像说明

真的很感激,帮助和洞察力,任何人都可以给!

编辑:(触摸移动添加)

 -(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]; 

}

您不能在drawRect: ,period中调用[self.layer renderInContext:] 。 正如你所想的, renderInContext:调用drawRect:如果它被执行,这将导致无限的recursion。

您应该单独呈现一本书,然后使用渲染的图像让用户在其上绘制。 一种方法是将自包含的绘图代码封装在UIGraphicsBeginImageContext() / UIGraphicsEndImageContext()块中,并使用drawRect:的结果图像。 另一种方法是使用两个不同的视图,这些视图不是彼此的子视图,其中一个绘制未改变的书,另一个绘制用户草图。

编辑:首先,你需要一个原始的图像(书页,不pipe)。 在不调用 [self.layer renderInContext:] 情况下 ,在UIGraphicsBeginImageContext() / UIGraphicsEndImageContext()块中绘制它,并将其保存在视图的ivar(比如self.currentImage )中。 在touchesMoved:withEvent:调用setNeedsDisplay (它会调用drawRect:为你)来更新视图。 在drawRect:使用self.currentImage drawRect:作为背景图片。

我希望我不太模糊。

Interesting Posts