Home > Articles > Programming > General Programming/Other Languages

  • Print
  • + Share This
This chapter is from the book

Recipe: Drawing Touches Onscreen

UIView hosts the realm of direct onscreen drawing. Its drawRect: method offers a low-level way to draw content directly, letting you create and display arbitrary elements using Quartz 2D calls. With touch and drawing, you can build concrete, manipulatable interfaces.

Recipe 1-7 combines gestures with drawRect to introduce touch-based painting. As a user touches the screen, the TouchTrackerView class builds a Bezier path that follows the user’s finger. To paint the progress as the touch proceeds, the touchesMoved:withEvent: method calls setNeedsDisplay. This, in turn, triggers a call to drawRect:, where the view strokes the accumulated Bezier path. Figure 1-3 shows the interface with a path created in this way.

Figure 1-3

Figure 1-3 A simple painting tool for iOS requires little more than collecting touches along a path and painting that path with UIKit/Quartz 2D calls.

Although you could adapt this recipe to use gesture recognizers, there’s really no point to it. The touches are essentially meaningless; they’re only provided to create a pleasing tracing. The basic responder methods (that is, touches began, moved, and so on) are perfectly capable of handling path creation and management tasks.

This example is meant for creating continuous traces. It does not respond to any touch event without a move. If you want to expand this recipe to add a simple dot or mark, you’ll have to add that behavior yourself.

Recipe 1-7 Touch-Based Painting in a UIView

@implementation TouchTrackerView
{
    UIBezierPath * path;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.multipleTouchEnabled = NO;
    }
    return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Initialize a new path for the user gesture
    path = [UIBezierPath bezierPath];
    path.lineWidth = IS_IPAD ? 8.0f : 4.0f;

    UITouch *touch = [touches anyObject];
    [path moveToPoint:[touch locationInView:self]];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Add new points to the path
    UITouch *touch = [touches anyObject];
    [self.path addLineToPoint:[touch locationInView:self]];
    [self setNeedsDisplay];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
        UITouch *touch = [touches anyObject];
        [path addLineToPoint:[touch locationInView:self]];
        [self setNeedsDisplay];
}

- (void)touchesCancelled:(NSSet *)touches
        withEvent:(UIEvent *)event
{
        [self touchesEnded:touches withEvent:event];
}

- (void)drawRect:(CGRect)rect
{
    // Draw the path
    [path stroke];
}
@end
  • + Share This
  • 🔖 Save To Your Account