How to draw a CALayer with a linear path, for example, simulate the effect of an eraser?

I want to simulate the effect of an eraser with a touch event to show an image that is behind something above, for example gray;

Something like that:

enter image description here

I found a long time to solve, but I canโ€™t do it well.

Below is my custom 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 simply mimics the fillable image at the back. I want to be an eraser, like a picture. Please, help.

+2
ios calayer uiview drawing cashapelayer
Jun 02 '14 at 2:56
source share
1 answer

Your code is close, but you need a custom layer class that has a gray background and draws the path as transparent. You can do it 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 slightly different, and you do not 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]; } 
+6
Jun 02 '14 at 17:19
source share



All Articles