+1  A: 

Header:

#import <UIKit/UIKit.h>

@interface myView : UIView {
    CGMutablePathRef path;
    CGPathRef drawingPath;
    CGRect start;
    BOOL outsideStart;
}

@end

Implementation:

#import "myView.h"

@implementation myView

- (id) init {
    if (self = [super init]) {
        self.userInteractionEnabled = YES;
        self.multipleTouchEnabled = NO;
    }
}

- (void) finishPath {
    if (drawingPath) {
        CGPathRelease(drawingPath);
    }
    CGPathCloseSubpath(path);
    drawingPath = CGPathCreateCopy(path);
    CGPathRelease(path);
    path = NULL;
    [self setNeedsDisplay];
    return;
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    path = CGPathCreateMutable();
    UITouch *t = [touches anyObject];
    CGPoint p = [t locationInView:self];
    start = CGRectZero;
    start.origin = p;
    start = CGRectInset(start,-10, -10);
    outsideStart = NO;
    CGPathMoveToPoint(path, NULL, p.x, p.y);
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    if (!path) {
        return;
    }
    UITouch *t = [touches anyObject];
    CGPoint p = [t locationInView:self];
    if (CGRectContainsPoint(start,p)) {
        if (outsideStart) {
            [self finishPath];
        }
    } else {
        outsideStart = YES;
    }
    CGPathAddLineToPoint(path,NULL,p.x,p.y);
    [self setNeedsDisplay];
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    if (!path) {
        return;
    }
    [self finishPath];
}

- (void) touchesCanceled:(NSSet *)touches withEvent:(UIEvent *)event {
    if (!path) {
        return;
    }
    CGPathRelease(path);
    path = NULL;
}

- (void) drawInRect:(CGRect)rect {
    CGContextRef g = UIGraphicsGetCurrentContext();
    if (drawingPath) {
        CGContextAddPath(g,drawingPath);
        [[UIColor redColor] setFill];
        [[UIColor blackColor] setStroke];
        CGContextDrawPath(g,kCGPathFillStroke);
    }
    if (path) {
        CGContextAddPath(g,path);
        [[UIColor blackColor] setStroke];
        CGContextDrawPath(g,kCGPathStroke);
    }
}

- (void) dealloc {
    if (drawingPath) {
        CGPathRelease(drawingPath);
    }
    if (path) {
        CGPathRelease(path);
    }
    [super dealloc];
}

@end

Note that you will probably want to do something so you aren't actually calling setNeedsDisplay every time the path changes. This can get very slow. Suggestions include having an NSTimer that fires every x milliseconds to check if it needs to redisplay and do so if it does, or only redrawing if the touch has moved a significant distance.

Ed Marty
i just want to draw circle or any shape.similer to circle.i have a uiimageview and set an image into it already.how do i use your code? i am adding an image to explain my question in more detail.
Rahul Vyas
i want to draw path first.then select colours from list and then fill the selected path.something like photoshop does.or we can say paint application of windows
Rahul Vyas
A: 

Core Graphics should definitely not be using [self setNeedsDisplay] every time the image changes, which is probably why your code is so slow on the device. Drawing is slow. If you use OpenGL ES to draw the lines, it will be much quicker, at the expense of being more difficult to understand.

Ed Marty
how do i use your code to draw line and detectpath.then fill path using bitmapcontext.is there a way to make drawing faster in core graphics.how do i use opengl in my pre created project.thanks for your help
Rahul Vyas
A: 

Maybe it can be useful to you link text

ilagnev