I\'m trying to implement a very simple drawing view in my app. This is only a small part of my app but it\'s turning into a real hassle. This is what I have so far, but all it\'
Don't draw while handling touches. It will slow down the touch handler so much you might get the connect-the-dots-effect you are seeing.
Save the touch coordinates in an array and plan to draw them later.
Look at some simple animation tutorials for how to draw in a drawRect based on a setNeedsDisplay called by an animation UITimer or CADisplayLink. Draw all your line segments there at a more suitable rate.
One of my apps also needed some simple drawing. Here is a slightly modified version of it. It works basically like hotpaw2 describes. I created a "canvas" view that handles all the drawing and I just add it wherever it's needed.
The speed is fine for my purposes.
CanvasView.h:
@interface CanvasView : UIView {
NSMutableArray *points;
}
@property (nonatomic, retain) NSMutableArray *points;
@end
CanvasView.m:
#import "CanvasView.h"
@implementation CanvasView
@synthesize points;
- (id) initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor blueColor];
}
return self;
}
-(void)drawRect:(CGRect)rect
{
if (self.points.count == 0)
return;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); //white
CGContextSetLineWidth(context, 1.0);
CGPoint firstPoint = [[self.points objectAtIndex:0] CGPointValue];
CGContextBeginPath(context);
CGContextMoveToPoint(context, firstPoint.x, firstPoint.y);
int i = 1;
while (i < self.points.count)
{
CGPoint nextPoint = [[self.points objectAtIndex:i] CGPointValue];
if (nextPoint.x < 0 && nextPoint.y < 0)
{
CGContextDrawPath(context, kCGPathStroke);
if (i < (self.points.count-1))
{
CGContextBeginPath(context);
CGPoint nextPoint2 = [[self.points objectAtIndex:i+1] CGPointValue];
CGContextMoveToPoint(context, nextPoint2.x, nextPoint2.y);
i = i + 2;
}
else
i++;
}
else
{
CGContextAddLineToPoint(context, nextPoint.x, nextPoint.y);
i++;
}
}
CGContextDrawPath(context, kCGPathStroke);
}
-(void)dealloc
{
[points release];
[super dealloc];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event touchesForView:self] anyObject];
CGPoint location = [touch locationInView:self];
if (self.points == nil)
{
NSMutableArray *newPoints = [[NSMutableArray alloc] init];
self.points = newPoints;
[newPoints release];
}
[self.points addObject:[NSValue valueWithCGPoint:(location)]];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event touchesForView:self] anyObject];
CGPoint location = [touch locationInView:self];
[self.points addObject:[NSValue valueWithCGPoint:(location)]];
[self setNeedsDisplay];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event touchesForView:self] anyObject];
CGPoint location = [touch locationInView:self];
[self.points addObject:[NSValue valueWithCGPoint:(location)]];
CGPoint endPoint = CGPointMake(-99, -99); //"end of path" indicator
[self.points addObject:[NSValue valueWithCGPoint:(endPoint)]];
[self setNeedsDisplay];
}
@end
Adding the canvasView where it's needed:
CanvasView *cv = [[CanvasView alloc] initWithFrame:CGRectMake(0, 0, 320, 640)];
[self.view addSubview:cv];
[cv release];