how to draw CALayer with line path like simulate eraser effect?
calayer, cashapelayer, drawing, ios, uiview
Solution
Your code is close, but what you need is a custom layer class that has a gray background, and draws the path as transparent. You can do that with code like this
RevealLayer.h
@interface RevealLayer : CALayer
@property (strong, nonatomic) UIBezierPath *drawingPath;
@end
RevealLayer.m
@implementation RevealLayer
- (UIBezierPath *)drawingPath
{
if ( !_drawingPath )
{
_drawingPath = [UIBezierPath new];
[_drawingPath moveToPoint:CGPointZero];
[_drawingPath setLineWidth:20.0];
[_drawingPath setLineCapStyle:kCGLineCapRound];
}
return( _drawingPath );
}
- (void)drawInContext:(CGContextRef)context
{
UIGraphicsPushContext( context );
[[UIColor darkGrayColor] set];
CGContextFillRect( context, self.bounds );
CGContextSetBlendMode( context, kCGBlendModeClear );
[self.drawingPath stroke];
UIGraphicsPopContext();
}
@end
Then the code for the custom view class is similar to what you already have. However, the setup is a little different and you don't need to implement the `drawRect:` method.
CustomView.m
@interface CustomView()
@property (strong, nonatomic) RevealLayer *revealLayer;
@end
@implementation CustomView
- (void)setup
{
self.userInteractionEnabled = YES;
[self setMultipleTouchEnabled:NO];
self.image = [UIImage imageNamed:@"transformers.jpg"];
self.revealLayer = [RevealLayer new];
self.revealLayer.frame = self.bounds;
self.revealLayer.backgroundColor = [[UIColor clearColor] CGColor];
[self.revealLayer setNeedsDisplay];
[self.layer addSublayer:self.revealLayer];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
[self.revealLayer.drawingPath moveToPoint:location];
[self.revealLayer setNeedsDisplay];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
[self.revealLayer.drawingPath addLineToPoint:location];
[self.revealLayer setNeedsDisplay];
}
Problem
I want to simulate eraser effect with touch event to show a image that behind something block on top, eg, gray color; Something like that: I have find for a long time for the solution but I can't do it well. following is my custom view code: CustomView.m: ``` -(id)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { [self setup]; } return self; } -(id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setup]; } return self; } -(void)setup { [self setMultipleTouchEnabled:NO]; [self setBackgroundColor:[UIColor darkGrayColor]]; self.drawingPath = [UIBezierPath bezierPath]; [self.drawingPath moveToPoint:CGPointZero]; [self.drawingPath setLineWidth:5.0]; self.image = [UIImage imageNamed:@"transformers.jpg"]; self.shapeLayer = [CAShapeLayer layer]; self.caLayer = [CALayer layer]; self.caLayer.frame = self.bounds; self.caLayer.contents = (id)(self.image.CGImage); [self.layer addSublayer:self.caLayer]; } - (void)drawRect:(CGRect)rect { self.shapeLayer.path = [self.drawingPath CGPath]; self.caLayer.mask = self.shapeLayer; self.shapeLayer.lineWidth = 5.0; } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint location = [touch locationInView:self]; [self.drawingPath moveToPoint:location]; lastPt = location; [self setNeedsDisplay]; NSLog(@"Touch Began"); } -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint location = [touch locationInView:self]; [self.drawingPath addLineToPoint:location]; [self setNeedsDisplay]; } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [self touchesMoved:touches withEvent:event]; } -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [self touchesMoved:touches withEvent:event]; } ``` However it just simulate the behind image fill in the path. I want to be eraser effect like the picture. Please help.