1

I have a UIImageView (wImage) in which I am trying to draw a line. The code runs fine in simulator but when I test it an a device it is super slow and creates a memory warning. Could someone please tell me what the problem is?

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint thirdPoint = lastPoint; lastPoint = [touch previousLocationInView:self.view]; CGPoint currentPoint = [touch locationInView:self.view]; CGPoint mid1 = CGPointMake((lastPoint.x+thirdPoint.x)/2, (lastPoint.y+thirdPoint.y)/2); CGPoint mid2 = CGPointMake((currentPoint.x+lastPoint.x)/2, (currentPoint.y+lastPoint.y)/2); UIGraphicsBeginImageContext(wImage.frame.size); CGContextSetAllowsAntialiasing(UIGraphicsGetCurrentContext(), true); CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), true); [wImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; CGContextMoveToPoint(UIGraphicsGetCurrentContext(), mid1.x, mid1.y); CGContextAddQuadCurveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y, mid2.x, mid2.y); CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush ); CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1); CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal); CGContextStrokePath(UIGraphicsGetCurrentContext()); wImage.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } 
4
  • For every single "touches moved" event you create a whole new image by drawing an image and stroking a complicated path. That's why it's slow. You can generate lots of "touches moved" events even when you think you aren't really moving your finger. Commented Aug 10, 2014 at 3:34
  • @rmaddy So what is the solution then? How do I draw the curve without updating the image on every move? Commented Aug 10, 2014 at 3:35
  • 3
    Why not have a view with the path drawing shown on top of the static image. Then you only have to update the path in the view and not generate a new image over and over. Commented Aug 10, 2014 at 3:36
  • @rmaddy Thanks for the suggestion. I am quite new to this though. Would you mind providing an example in code? Commented Aug 10, 2014 at 3:39

1 Answer 1

2

You are having such a performance problem because you are actually doing a ton of work to create a new image every time the user's finger moves. Don't draw directly on the image itself, create a UIView that is responsible for the user's drawing, with a transparend background. There's a good amount you can do with it, and I couldn't possibly put all the code here, but there is a great tutorial, complete with some really cool code to smooth out the line as the user is drawing. It results in a much nicer looking path. Here it is:

http://code.tutsplus.com/tutorials/smooth-freehand-drawing-on-ios--mobile-13164

Go ahead and read through all the sections - it would be good for you to understand what's going on rather than just trying the last implementation.

For your implementation, make sure the view has a transparent background, so you can see the ImageView underneath.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Looks like I need to change my approach.
Don't be intimidated by the article... I created the class as in the article and dropped it into one of my projects in about 2 minutes and the results are impressive.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.