Search code examples
iosobjective-ccgcontexttouchesbegantouchesmoved

CGcontext drawing on image not working


This is my code and it makes a very weird drawing when executed. Moreover image starts to disappear slowly by going down the imageview. Please help me with this

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];

//    if ([touch tapCount] == 2)
//    {
//        imageView.image = nil;
//    }

location = [touch locationInView:touch.view];
lastClick = [NSDate date];

lastPoint = [touch locationInView:self.view];
lastPoint.y -= 0;

[super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{mouseSwiped = YES;

UITouch *touch = [touches anyObject];
currentPoint = [touch locationInView:self.view];

UIGraphicsBeginImageContext(imageView.image.size);

[imageView.image drawInRect:CGRectMake(0, 44, imageView.image.size.width, imageView.image.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);

CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0, 1, 0, 1);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());

imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
 //   lastPoint = currentPoint;


}

Moreover, the lines its drawing are of weird shape and they are disappearing continously


Solution

  • Your image is shifting, because you hardcoded offset in 44 points on each redraw.

    Weird drawing is most likely the result of invalid coordinate system usage. You receive touch location in view coordinates, but draw in image coordinates. The easiest way to fix this issue is to create context with size, equal to view size instead of image size. Simply use imageView.bounds.size instead of imageView.image.size. Note that I assume you use "Scale to Fill" mode in your image view.

    Whole drawing code after changes:

    UIGraphicsBeginImageContext(self.imageView.bounds.size);
    
    [self.imageView.image drawInRect:CGRectMake(0, 0, self.imageView.bounds.size.width, self.imageView.bounds.size.height)];
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
    
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0, 1, 0, 1);
    CGContextBeginPath(UIGraphicsGetCurrentContext());
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.lastPoint.x, self.lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    
    self.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

    Also, your solution is not optimal in terms of performance. I suggest to draw path separately in view, instead of updating imageView image on each touch move.