In this tutorial you will learn how to handle touch events and the basics of Quartz 2D. I will show you how to create a simple Paint app to draw with your finger. There are four different functions called during a touch sequence, although in this tutorial we will only need to implement two of them.
- - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; – when the screen is touched.
- - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; – when one or more fingers move.
- - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; – when the finger lifts up from the screen.
- - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; – when the touch sequence is cancelled by a system event.
We will use the second one to draw, and the first one to reset the view if the user taps the screen twice.
Step 1: Creating the project
Create a new Single View Application project and delete the view controller that is generated by default: ViewController.h and ViewController.m. Then create a new file and select Objective-C class. Name it PaintView and set its superclass to UIView.
Now, go to the storyboard and select the View Controller. In the Identity Inspector, set its class to UIViewController. Next, select the View and set its class to PaintView.
Step 2: Declaring the instance variables
You are going to need to declare three instance variables in your PaintView header file. Two of them will be CGPoints, since you need to save two points in the screen: the last one the user touched, and the previous one. This way, you can draw a line between them. The third variable will be of type CGMutablePathRef. CGMutablePathRef is a mutable CGPath object to which you can add lines, arcs, curves, and rectangles.
#import <UIKit/UIKit.h>
@interface PaintView : UIView {
CGPoint previousPoint;
CGPoint lastPoint;
CGMutablePathRef path;
}
@end
Step 3: Handling touch events
In PaintView.m, add the following code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ([touch tapCount] > 1) {
path = CGPathCreateMutable();
previousPoint = lastPoint;
[self setNeedsDisplay];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
lastPoint = [[touches anyObject] locationInView:self];
previousPoint = [[[touches anyObject] previousLocationInView:self];
[self setNeedsDisplay];
}
In the first method, we control if the user tapped the screen more than once. If so, then we need to clear the screen. To do so, we create a new path, and make previousPoint the same as lastPoint, otherwise a line will be drawn between those two points.
Finally, we call setNeedsDisplay to update our UI.
The second method only saves both points and updates the UI.
Step 4: Overriding drawRect
You need to override the drawRect method to make your view draw custom content. The first thing you need to do is to get the current graphics context. Then, move path to previousPoint, and add a line from this point to the last one. Next, you need to add the path to the current context, and set some parameters like the color of the stroke, the width, etc. Finally, you have to call CGContextDrawPath to draw the path you have created. This is the code to do all this:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGPathMoveToPoint(path, NULL, previousPoint.x, previousPoint.y);
CGPathAddLineToPoint(path, NULL, lastPoint.x, lastPoint.y);
CGContextAddPath(context, path);
CGContextSetLineWidth(context, 2.0);
[[UIColor blueColor] setStroke];
CGContextDrawPath(context, kCGPathFillStroke);
}
Step 5: Initializing the path
There is one last thing you need to do. As you might have noticed, in drawRect we used path, but we haven’t initialized it yet. Therefore, you will need to add this method, which is called when the view is created:
- (void)awakeFromNib
{
path = CGPathCreateMutable();
}
Conclusion
Handling touch events is very easy, and you can use classes provided by apple to recognize certain gestures like UIPanGestureRecognizer. Consider this tutorial as your first approach to touch events and specially to Quartz 2D, a very powerful but very complicated drawing engine for iOS development.
EOF