I want to implement a Highlight function in my pdf reader app. Unfortunately, my research yielded very few information about this. However, I came to believe that I will have to use an "overlay" where the drawing or "highlighting" must be done. What I plan to do now is add a CALayer into the pdf. I am successful in rendering shapes into the layer (e.g a simple line, circle, and a square), but I can't seem to draw freely into it (like in Draw Something). Here is the code I used:
When the user begins highlighting:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
prevPoint = [touch locationInView:theContentView];
drawImageLayer = [CALayer layer];
drawImageLayer.frame = theContentView.frame;
[theContentView.layer addSublayer:drawImageLayer];
}
When the user is starting the highlighting:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
currPoint = [touch locationInView:theContentView];
drawImageLayer.delegate = self;
[drawImageLayer setNeedsDisplay];
}
This is the code where the drawing happens:
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
NSLog(@"DrawLayer being called..");
CGContextSaveGState(ctx);
CGContextSetLineCap(ctx, kCGLineCapRound);
CGContextSetLineWidth(ctx, 1.0);
CGContextSetRGBStrokeColor(ctx, 1, 0, 0, 1);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, prevPoint.x, prevPoint.y);
CGContextAddLineToPoint(ctx, currPoint.x, currPoint.y);
CGContextStrokePath(ctx);
prevPoint = currPoint;
CGContextRestoreGState(ctx);
}
What happens is that it draws a point and that point follows the cursor everywhere! Can anyone tell me what's wrong with this code?
drawLayer:
redraws the entire layer; it does not keep what was previously drawn. You draw a line from prevPoint
to currPoint
then update currPoint
. Since drawLayer:
will be called whenever you update currPoint
(since you call setNeedsDisplay
), prevPoint
will be very close to currPoint
, which is why you basically just see a point following the user's finger.
If you want a straight line starting where the user touched down and ending where the user's finger currently is, you probably want to just get rid of the line
prevPoint = currPoint;
, which will thus always draw a line from where the user first touched down to where the users' finger currently is.
If you want a smooth line that follows the user's finger, then you'll need to keep track of a list of points, and connect all of them together in drawLayer
. In practice, since touchesMoved:
is not called after every single-pixel move, you might have to interpolate a curve that smoothly connects all the points.