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 fromprevPointtocurrPointthen updatecurrPoint. SincedrawLayer:will be called whenever you updatecurrPoint(since you callsetNeedsDisplay),prevPointwill be very close tocurrPoint, 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, sincetouchesMoved:is not called after every single-pixel move, you might have to interpolate a curve that smoothly connects all the points.