Drawing

August 8, 2009 by Skylar
Filed under: iPhone Development 

Want to create a drawing app? Here you go. Clearly, you will need to make improvements to the drawing code, as I literally spent five minutes making this to test something for another app. Regardless, you should be able to get the gist of what’s going on. What I am linking is just your basic standard xcode view based project. The only pertinent part of this are the touchsBegan, touchesMoved, and touchesEnded methods, which I will be posting in this thread.

To draw, simply draw. To move your finger over the screen. To create a dot, tap the screen. To clear the screen, double tap the screen. Simple.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {                 mouseSwiped = NO;         UITouch *touch = [touches anyObject];                 if ([touch tapCount] == 2) {                 drawImage.image = nil;                 return;         }         lastPoint = [touch locationInView:self.view];         lastPoint.y -= 20; }

The first thing we do is set a bool to track whether or not we moved our finger across the screen. Since this is when we touch, we will set it (mouseSwiped) to NO. After getting our touch, we want to know whether the user double tapped. If they did, we set our canvas to an empty image and break out of the touchesBegan method. If we are still going through our code, that means that the user did not double tap. We will now set a CGPoint ivar we set to where we user tapped the screen. This is so we know from where the user moved their finger.

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {         mouseSwiped = YES;                 UITouch *touch = [touches anyObject];           CGPoint currentPoint = [touch locationInView:self.view];         currentPoint.y -= 20;                         UIGraphicsBeginImageContext(self.view.frame.size);         [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];         CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);         CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);         CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);         CGContextBeginPath(UIGraphicsGetCurrentContext());         CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);         CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);         CGContextStrokePath(UIGraphicsGetCurrentContext());         drawImage.image = UIGraphicsGetImageFromCurrentImageContext();         UIGraphicsEndImageContext();                 lastPoint = currentPoint; }

First off, before we forget, let’s set our mouseSwiped flag to YES, that way we can refer to it later. Next, let’s get the location where the user moved their finger. We’ll set that location to currentPoint.

Graphics Contexts are byond the scope of this post. Instead, and also because it would be overkill in this scenario, we will not be creating our own. Instead, we will be using a shortcut within UIKit called UIGraphicsGetCurrentContext() to gather the current context in which to work.

Begin the context with the size of our view in which we want to draw, and draw an image into it. We now want to set our line caps. This is what makes our lines not end in squares and look natural. There are other caps you can use, so feel free to experiment. Next, we’re going to want to set the color with which we will be working. In this case, red.

Then, begin the actual drawing, we’ll need to call CGContextBeginPath(…) and fill it in. First, we’ll move to the point where we’d like to start. This is the point where the user tapped. Then, we’ll call CGContextAddLineToPoint to add a line to the point we just set. The line extends from the first point you set to the point you set within AddLineToPoint function call. Finally, call CGContextStrokePath to stroke the path, ie color the line you just made.

And you have a line in your context, congrats. Let’s create an image out of that and set it as our canvas. Make sure to end the context with which we ar eworking: UIGraphicsEndImageContext(); We want to reset the the touch down point as the point to where we just drew. This way, if the user keeps swiping, we can start from where we left off.

Lastly, and importantly, ignore that mouseMoved variable. In fact, delete it from your code. Seriously.

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {                 UITouch *touch = [touches anyObject];                 if ([touch tapCount] == 2) {                 drawImage.image = nil;                 return;         }                         if(!mouseSwiped) {                 UIGraphicsBeginImageContext(self.view.frame.size);                 [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];                 CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);                 CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);                 CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);                 CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);                 CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);                 CGContextStrokePath(UIGraphicsGetCurrentContext());                 CGContextFlush(UIGraphicsGetCurrentContext());                 drawImage.image = UIGraphicsGetImageFromCurrentImageContext();                 UIGraphicsEndImageContext();         } }

In the touchesEnded method, the first thing we want to do is break out of the user double tapped. This is because the user has already cleared their canvas.

Now, if we are still in the function, then the user has not double tapped. Check to make see if the user has swiped. If they have, do nothing, we’ve already drawn, and there’s no reason to do anything else.

Else, if the user did not swipe, we want to make a dot. Simply do exactly what we did in the touchesMoved. Only, instead of drawing a line, we draw a point.

Congrats, you now can draw within your application. Enjoy it.

Download: http://www.touchrepo.com/SampleCode/TEST_DRAW_APP.zip

More comments: ipodtouchfans.com

Comments

2 Comments on Drawing

  1. Alex Dixon on Sat, 8th Aug 2009 11:38 pm
  2. For a noobie who’s never coded in their life and wants to start, what’s the best language to start off with in order to work up to Obj-C? I was thinking of trying JS first… might help me get a hang on the lingo faster…

    But I do like your blog! Very good idea :)

    [WORDPRESS HASHCASH] The poster sent us ‘0 which is not a hashcash value.

  3. Paul on Fri, 19th Mar 2010 7:37 am
  4. Alex,
    Before you learn Obj-C, you should learn C. You can start learning C right away if you’re dedicated and have an open mind! From C, you can figure out Obj-C after reading some basic tutorials. But please keep in mind that you need to learn things like what is a variable, what is an algorithm, what is flow control, function use, and things like that.
    Paul.

Tell me what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!





Powered by WP Hashcash