问题描述
我想用触摸事件来模拟橡皮擦效果,以显示顶部阻挡背后的图像,例如灰色;
I want to simulate eraser effect with touch event to show a image that behind something block on top, eg, gray color;
类似的东西:
我已经找到了很长时间的解决方案,但我不能做得很好。
I have find for a long time for the solution but I can't do it well.
以下是我的自定义视图代码:
CustomView.m:
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.
推荐答案
您的代码很接近,但您需要的是一个灰色的自定义图层类背景,并将路径绘制为透明。你可以用这样的代码做到这一点
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
然后自定义视图类的代码类似到你已经拥有的。但是,设置稍有不同,您不需要实现 drawRect:
方法。
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];
}
这篇关于如何使用线条路径绘制CALayer,如模拟橡皮擦效果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!