0

So I'm working on an iOS app that has a GUI where you can draw on an image, add filters, etc. The drawing feature works, but will randomly cut out sometimes right at the start of drawing. Basically, if you start drawing on the screen and it works for more than half a second, your set, it will work until you try again; however sometimes when you start drawing, it will cut out after a split second for seemingly no reason.

// Draws a line from point1 to point2
- (void) drawOnImage:(CGPoint *)point1 :(CGPoint *)point2 {
    UIGraphicsBeginImageContext(self.view.frame.size);
    [self.mainImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), point1->x, point1->y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), point2->x, point2->y);
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush );
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
    CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

}

// Beginning of the drawing, only happens when you click but don't move around on the screen
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    lastPoint = [touch locationInView:self.view];

    if (currentAction == DRAW) {
        [self backupImage];

        //disable the renderImageView so that the gestures dont interfere


        [self drawOnImage :&lastPoint :&lastPoint];
    }
}

// When lines are being drawn on the image (when your finger is moving)
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    if (currentAction == DRAW) {
        UITouch *touch = [touches anyObject];
        CGPoint currentPoint = [touch locationInView:self.view];
        [self drawOnImage :&currentPoint :&lastPoint];
        lastPoint = currentPoint;

    }
}

Here's my storyboard layout; as you can see, the code creates CGRects of a line as the user draws, then re-generates the main image with the CGRect as a part of the image.

storyboard

Here's An example of the issue, see the two black drawing marks that ended immediately? The top draw worked and followed through, the other two immediately cut out then didn't render any other lines after that.

issue

Any ideas why this happens? At first we thought it was the simulator, but its not.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
Grant_E
  • 13
  • 2
  • I don't see anything here that would cause the behavior you describe. Sure, this is probably not as efficient as it could be, but I see no reason for it to "cut out". I'd suggest putting logging messages inside a few of these routines, so you can narrow it down (is it not receiving the `touchesMoved` at all, or is it in the drawing). – Rob Aug 04 '16 at 17:43
  • Hey i actually fixed the issue. I'm not sure what did it, but ill give my best idea in a post below – Grant_E Aug 04 '16 at 18:23
  • Yeah, the problem was not in the code provided in the question. I tested it and it worked fine. It must have been something else (e.g. something was setting `currentAction` to something other than `DRAW`, something blocking the main queue, etc.). – Rob Aug 04 '16 at 18:26
  • A few unrelated suggestions for you: 1. When you redraw the image, you might want to use `UIGraphicsBeginImageContextWithOptions` with a scale of `0`. Right now, on retina devices, the image will be a little pixelated. 2. Rather than redrawing the whole image every time, consider using a `CAShapeLayer` with a path. It will be far more performant. Only do this snapshot approach (and reset the path) every 50-100 points. Your paths will be far smoother if you do this. 3. Consider using coalesced touches (to smooth it) and predictive touches (to make it feel more responsive). – Rob Aug 04 '16 at 18:34
  • If you're interested here is a post that shows how to draw smooth paths. It's a Swift implementation, but illustrates some of the concepts I've discussed above. http://stackoverflow.com/a/34583708/1271826 – Rob Aug 04 '16 at 19:48

1 Answers1

0

Fixed the issue in the process of fixing another issue. I think i had gesture recognizer confusion (which really shouldn't have happened because there should only be one gesture going when the touch is moving with one finger), try setting gesture recognizer delegates to the correct view (usually self) and if you have the

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

function implemented, tell it to only return true in certain situations. I doubt anyone will have this exact issue, though, so posting this solution is probably kind of useless.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
Grant_E
  • 13
  • 2