ios - 如何绘制CALayer 的线路径模拟橡皮擦效果?

标签 ios uiview drawing calayer cashapelayer

我想用触摸事件模拟橡皮擦效果,以显示在某些东西后面的图像在顶部,例如灰色;

类似的东西:

enter image description here

我找了很久的解决方案,但我做不好。

以下是我的自定义 View 代码: 自定义 View .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];
}

但是它只是模拟后面的图像填充路径。 我想要像图片一样的橡皮擦效果。 请帮忙。

最佳答案

您的代码很接近,但您需要的是具有灰色背景并将路径绘制为透明的自定义图层类。你可以用这样的代码来做到这一点

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

然后自定义 View 类的代码与您已有的代码类似。但是,设置略有不同,您不需要实现 drawRect: 方法。

自定义 View .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];
}

关于ios - 如何绘制CALayer 的线路径模拟橡皮擦效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23997525/

相关文章:

ios - 如何将 UITableView 放入 UIView

java - 单击按钮Android后绘制

objective-c - 高效地绘制数千个矩形并为其设置动画

iOS:Google+ 按钮在 XIB 文件中不起作用?

iOS 7 UIPickerView 非选中行曲率修改多个组件

iOS Popover 或 ActionSheet 导致 UISegmentedControl 按钮变灰

Swift:以编程方式添加按钮,而无需在初始化期间提供框架

ios - 在 iOS9 中捕获实时照片的 API

ios - 将 UIView subview 附加到父 View

android - 以编程方式创建带圆角的图层列表