Q:

Draw straight line with two fingers

How can I paint/draw a straight line with 2 fingers with the line being visible while the dragging or touching is still being done by the user? I've already tried simple painting using coregraphics but this one seems a bit complicated for me.

A:

To Justin's point, just handle touchesBegan and touchesMoved.
Thus, if you subclass UIView, the CoreGraphics implementation might look like:
@interface CustomView ()

@property (nonatomic, strong) NSMutableArray *paths;
@property (nonatomic, strong) UIBezierPath *currentPath;

@end

@implementation CustomView

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setMultipleTouchEnabled:YES];
    }
    return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.currentPath)
    {
        if (!self.paths)
            self.paths = [NSMutableArray array];

        self.currentPath = [UIBezierPath bezierPath];
        self.currentPath.lineWidth = 3.0;

        [self.paths addObject:self.currentPath];

        [self touchesMoved:touches withEvent:event];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if ([touches count] != 2)
        return;

    [self.currentPath removeAllPoints];

    __block NSInteger i = 0;
    [touches enumerateObjectsUsingBlock:^(UITouch *touch, BOOL *stop) {
        CGPoint location = [touch locationInView:self];

        if (i++ == 0)
            [self.currentPath moveToPoint:location];
        else
            [self.currentPath addLineToPoint:location];
    }];

    [self setNeedsDisplay];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.currentPath = nil;
}

- (void)drawRect:(CGRect)rect
{
    [[UIColor redColor] setStroke];
    [[UIColor clearColor] setFill];

    for (UIBezierPath *path in self.paths)
    {
        [path stroke];
    }
}

- (void)reset
{
    self.paths = nil;
    [self setNeedsDisplay];
}

@end

Alternatively, you can also use Quartz 2D and define your own CAShapeLayer objects, and then either your view subclass or your view controller could do something like (needless to say, this is the view controller implementation; the view implementation should be obvious):
#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

@property (nonatomic, weak) CAShapeLayer *currentLayer;
@property (nonatomic, strong) UIBezierPath *currentPath;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.view setMultipleTouchEnabled:YES];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.currentLayer)
    {
        CAShapeLayer *layer = [CAShapeLayer layer];
        layer.lineWidth = 3.0;
        layer.strokeColor = [[UIColor redColor] CGColor];
        layer.fillColor = [[UIColor clearColor] CGColor];
        [self.view.layer addSublayer:layer];
        self.currentLayer = layer;

        self.currentPath = [UIBezierPath bezierPath];

        [self touchesMoved:touches withEvent:event];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if ([touches count] != 2)
        return;

    [self.currentPath removeAllPoints];

    __block NSInteger i = 0;
    [touches enumerateObjectsUsingBlock:^(UITouch *touch, BOOL *stop) {
        CGPoint location = [touch locationInView:self.view];

        if (i++ == 0)
            [self.currentPath moveToPoint:location];
        else
            [self.currentPath addLineToPoint:location];
    }];

    self.currentLayer.path = [self.currentPath CGPath];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.currentPath = nil;
    self.currentLayer = nil;
}

- (IBAction)didTouchUpInsideClearButton:(id)sender
{
    for (NSInteger i = [self.view.layer.sublayers count] - 1; i >= 0; i--)
    {
        if ([self.view.layer.sublayers[i] isKindOfClass:[CAShapeLayer class]])
            [self.view.layer.sublayers[i] removeFromSuperlayer];
    }
}

@end

For this latter approach, you need to add the QuartzCore.framework to your project.

