简体   繁体   English

drawRect:/ renderInContext:问题

[英]drawRect:/renderInContext: issues

Seem to be having a bit of an issue trying to draw my view into a context. 试图将我的观点吸引到上下文中似乎有点问题。

My basic setup is, I have a view controller that owns a UIPageViewController in which I load controllers with views that can be drawn on by the users finger. 我的基本设置是,我有一个拥有UIPageViewController的视图控制器,在其中向控制器加载可以由用户手指绘制的视图的控制器。 Basically I have a book that can be drawn in. 基本上我有一本书可以画。

When the page is turned in the book I save the image by calling 当书中翻页时,我通过调用保存图像

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

The return value of this then gets saved to a file. 然后将其返回值保存到文件中。 However when I call this save method then line 但是,当我调用此保存方法时,

[self.layer renderInContext:UIGraphicsGetCurrentContext()];

gets hit, which seems to make a call to my drawRect: method, which is overridden as follows, 被击中,似乎调用了我的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];
}

which makes sense, but it seems to get called recursively until eventually I get an EXC_BAD_ACCESS on this line 这是有道理的,但是它似乎是递归调用的,直到最终我在此行上得到EXC_BAD_ACCESS

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

Am at a complete loss as to what is causing this and has been driving me nuts. 我完全不知道是什么原因造成的,并且一直让我发疯。

If it helps, my call stack starts like this 如果有帮助,我的调用堆栈将像这样开始

在此处输入图片说明

and then goes on recursively until it finally ends with 然后递归进行直到最后以

在此处输入图片说明

Would really appreciate and help and insight that anyone can give!! 非常感谢任何人都可以给予的帮助和见解!!

EDIT: (Touches moved added) 编辑:(添加了触摸移动)

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

} }

You must not call [self.layer renderInContext:] in drawRect: , period. 您一定不要在drawRect:期间调用[self.layer renderInContext:] As you have figured out, renderInContext: calls drawRect: if it is implemented, which will cause an infinite recursion. 如您renderInContext:renderInContext:调用drawRect:如果实现了),这将导致无限递归。

You should render a book as is separately, then use the rendered image to let users draw on top of it. 您应该单独渲染一本书,然后使用渲染的图像让用户在其上绘画。 One way to do that is to enclose a self-contained drawing code in the UIGraphicsBeginImageContext() / UIGraphicsEndImageContext() block and use the resulting image in drawRect: . 一种方法是在UIGraphicsBeginImageContext() / UIGraphicsEndImageContext()块中包含一个自包含的绘图代码,并在drawRect:使用生成的图像。 Another way is to use two different views which are not subviews of each other, one drawing an unaltered book, the other drawing user sketches. 另一种方法是使用两个彼此都不是子视图的不同视图,一个绘制未更改的书,另一个绘制用户草图。

EDIT: first of all, you need an original image (book page, whatever). 编辑:首先,您需要一个原始图像(书页,无论如何)。 Draw it inside a UIGraphicsBeginImageContext() / UIGraphicsEndImageContext() block without calling [self.layer renderInContext:] and save it in the view's ivar (say, self.currentImage ). 将其绘制在UIGraphicsBeginImageContext() / UIGraphicsEndImageContext()块内, 而无需调用 [self.layer renderInContext:]并将其保存在视图的ivar中(例如self.currentImage )。 In touchesMoved:withEvent: call setNeedsDisplay (it will call drawRect: for you) to update the view. touchesMoved:withEvent:调用setNeedsDisplay (它将为您调用drawRect:以更新视图。 Use self.currentImage in drawRect: as the background image. drawRect:使用self.currentImage作为背景图像。

I hope I'm not too vague. 我希望我不要太含糊。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM