I'm using CoreGraphics to draw a line. I have just updated Xcode 10 and iOS 12. In iOS 12, my Application is crashed. Although, it still works well in iOS 11.4.1 and version before. I am not able to solve the issue. please find my code below
-(void)drawRect:(CGRect)rect
{
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.layer renderInContext:context];
CGContextMoveToPoint(context, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, self.lineWidth);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
CGContextSetShadow(context, CGSizeMake(-16.00, -5.0f), 5.0f);
CGContextStrokePath(context);
[super drawRect:rect];
[curImage release];
}
Below is the touchesMoved
method.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
previousPoint2 = previousPoint1;
previousPoint1 = [touch previousLocationInView:self];
currentPoint = [touch locationInView:self];
// calculate mid point
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(path, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGRect bounds = CGPathGetBoundingBox(path);
CGPathRelease(path);
CGRect drawBox = bounds;
//Pad our values so the bounding box respects our line width
drawBox.origin.x -= self.lineWidth * 2;
drawBox.origin.y -= self.lineWidth * 2;
drawBox.size.width += self.lineWidth * 4;
drawBox.size.height += self.lineWidth * 4;
UIGraphicsBeginImageContext(drawBox.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
curImage = UIGraphicsGetImageFromCurrentImageContext();
[curImage retain];
UIGraphicsEndImageContext();
[self setNeedsDisplayInRect:drawBox];
}
CGPoint midPoint(CGPoint p1, CGPoint p2)
{
return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
previousPoint1 = [touch previousLocationInView:self];
previousPoint2 = [touch previousLocationInView:self];
currentPoint = [touch locationInView:self];
[self touchesMoved:touches withEvent:event];
}
The issue is code crash at [self.layer renderInContext:context];
of (void)drawRect:(CGRect)rect
function. drawRect function is called too much time (About 5000 times) and Overload of Memory (About 20Gb) cause crashing app.
Could there be changes in iOS 12 and Xcode 10?
I Fixed this issue. Update my new toucheMoved() function:
- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
previousPoint2 = previousPoint;
previousPoint = [touch previousLocationInView:self];
location = [touch locationInView:self];
CGPoint mid1 = midPoint(previousPoint, previousPoint2);
CGPoint mid2 = midPoint(location, previousPoint);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(path, NULL, previousPoint.x, previousPoint.y, mid2.x, mid2.y);
CGRect bounds = CGPathGetBoundingBox(path);
CGPathRelease(path);
CGRect drawBox = bounds;
drawBox.origin.x -= self.lineWidth * 2;
drawBox.origin.y -= self.lineWidth * 2;
drawBox.size.width += self.lineWidth * 4;
drawBox.size.height += self.lineWidth * 4;
UIGraphicsBeginImageContextWithOptions(totalDrawBox.size, self.opaque, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGAffineTransform affineMoveLeftTop = CGAffineTransformMakeTranslation(-(int)totalDrawBox.origin.x, -(int)totalDrawBox.origin.y);
CGContextConcatCTM(context, affineMoveLeftTop);
float iOSVersion = [[UIDevice currentDevice].systemVersion floatValue];
if (iOSVersion >= 12) {
[self setNeedsDisplay];
} else {
[self.layer renderInContext: context];
}
curImage = UIGraphicsGetImageFromCurrentImageContext();
CGContextStrokePath(context);
UIGraphicsEndImageContext();
}
My work around is
Don't let layer renderInContext recursive call in drawRect
(My code is swift)
var mIsInDrawLoop = false
// -(void)drawRect:(CGRect)rect
override func draw(_ rect: CGRect) {
...
if(!mIsInDrawLoop) {
mIsInDrawLoop = true
layer.render(in: context)
// [self.layer renderInContext:context];
mIsInDrawLoop = false
}
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With