如何擦除 iPhone 中自定义 UIView 上的手指画

Posted

技术标签:

【中文标题】如何擦除 iPhone 中自定义 UIView 上的手指画【英文标题】:How to erase finger paint on Custom UIView in iPhone 【发布时间】:2012-06-21 06:17:05 【问题描述】:

我为手指绘画应用程序创建了一个自定义 UIView(没有 .xib)。

Paint 在自定义 UIView 上运行良好,但我的问题是,当我尝试擦除所绘制的路径时:

错误:上下文无效

下面是我的课:

.h 文件

@interface draw2D : UIView

    CGPoint previousPoint;
    CGPoint lastPoint;
    CGMutablePathRef path;
    UIButton *btnClose;
    UIButton *btnErase;
    BOOL IsErase;

- (IBAction)btnClose:(id)sender;
- (IBAction)btnErase:(id)sender;
@end


@implementation draw2D
- (void)awakeFromNib

    path = CGPathCreateMutable();

- (id)initWithFrame:(CGRect)frame

    self = [super initWithFrame:frame];
    if (self) 
    
        btnClose = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [btnClose addTarget:self action:@selector(btnClose:)
         forControlEvents:UIControlEventTouchDown];
        [btnClose setTitle:@"close" forState:UIControlStateNormal];
        btnClose.frame = CGRectMake(10, 10, 100, 40.0);

        btnErase = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [btnErase addTarget:self action:@selector(btnErase:)
           forControlEvents:UIControlEventTouchDown];
        [btnErase setTitle:@"Erase" forState:UIControlStateNormal];
        btnErase.frame = CGRectMake(150, 10, 100, 40.0);

        [self addSubview:btnClose];
        [self addSubview:btnErase];
    
    return self;


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    
    UITouch *touch = [touches anyObject];
    NSLog(@"Touch Began :%d",[touch tapCount]);

    if ([touch tapCount] > 1) 
    
        NSLog(@"::::: Paint Start :::::");
        path = CGPathCreateMutable();
        previousPoint = lastPoint;
        [self setNeedsDisplay];
    
    self.backgroundColor = [UIColor clearColor];


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 

    NSLog(@"::::: touchesMoved :::::");
    lastPoint = [[touches anyObject] locationInView:self];
    previousPoint = [[touches anyObject] previousLocationInView:self];

    if(IsErase)
    
        NSLog(@"erase");
        UITouch *erasetouch = [touches anyObject];  
        CGPoint erasecurrentPoint = [erasetouch locationInView:self];

        CGContextRef erasecontext = UIGraphicsGetCurrentContext();
        CGContextSetLineCap(erasecontext, kCGLineCapRound);
        CGContextSetLineWidth(erasecontext,10);
        CGContextSetBlendMode(erasecontext, kCGBlendModeClear);
        CGContextSetStrokeColorWithColor(erasecontext, [[UIColor clearColor] CGColor]);
        CGContextBeginPath(erasecontext);
        CGContextMoveToPoint(erasecontext, lastPoint.x, lastPoint.y);
        CGContextAddLineToPoint(erasecontext, erasecurrentPoint.x, erasecurrentPoint.y);
        CGContextStrokePath(erasecontext);     
        CGContextFlush(erasecontext);

      

    [self setNeedsDisplay];

- (void)drawRect:(CGRect)rect

    NSLog(@"::::: drawRect :::::");

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGPathMoveToPoint(path, NULL, previousPoint.x, previousPoint.y);
    CGPathAddLineToPoint(path, NULL, lastPoint.x, lastPoint.y);
    CGContextAddPath(context, path);
    CGContextSetLineWidth(context, 5);
    [[UIColor blueColor] setStroke];
    CGContextDrawPath(context, kCGPathFillStroke);


- (IBAction)btnClose:(id)sender

    [self removeFromSuperview];

- (IBAction)btnErase:(id)sender

    IsErase = YES;
    

@end

我设置了具有功能但不起作用的擦除按钮。

【问题讨论】:

请检查这个答案这真的很完美***.com/questions/3863931/… 【参考方案1】:

你遇到的问题是你不应该在drawRect:之外打电话给UIGraphicGetContext()

在您的touchesBegan:withEvent:touchesMoved:withEvent: 中,您应该简单地存储您想要绘制的点并像现在一样调用[self setNeedsDisplay]。 然后,在您的 drawRect: 实现中,您将绘制已存储的点。

你可以看看这个 github repo,它提供了一个平滑绘图的实现:https://github.com/levinunnink/Smooth-Line-View

【讨论】:

谢谢 .. 示例帮助我制作出色的手指画应用程序。但是是的,擦除功能呢?如何在github demo中实现?【参考方案2】:

我终于找到了解决方案。我的错误是我用新的contexttouchMove 方法中实现擦除代码。我不需要新的context。在drawrect 方法中实现擦除代码,现在它工作正常。请参阅下面的代码。

- (void)drawRect:(CGRect)rect


    [curImage drawAtPoint:CGPointMake(0, 0)];
    CGPoint mid1 = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2 = midPoint(currentPoint, previousPoint1);

    context = UIGraphicsGetCurrentContext(); 
    [self.layer renderInContext:context];

    if(IsErase)
    
        CGContextSetLineWidth(context,self.lineWidth);
        CGContextSetBlendMode(context, kCGBlendModeClear);
        CGContextSetStrokeColorWithColor(context, [[UIColor clearColor] CGColor]);
        CGContextBeginPath(context);
        CGContextMoveToPoint(context, mid1.x, mid1.y);
        CGContextAddLineToPoint(context, previousPoint1.x, previousPoint1.y);
        CGContextStrokePath(context);     
        CGContextFlush(context);
    
    else
    
        CGContextMoveToPoint(context, mid1.x, mid1.y);
        CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); 
        CGContextSetLineCap(context, kCGLineCapRound);
        CGContextSetLineWidth(context, self.lineWidth);
        CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
        CGContextSaveGState(context);
        CGContextStrokePath(context);
    
    [super drawRect:rect];
    [curImage release];

我希望它对擦除功能的人有所帮助。

【讨论】:

以上是关于如何擦除 iPhone 中自定义 UIView 上的手指画的主要内容,如果未能解决你的问题,请参考以下文章

在iPhone中自定义TabBar

UITableViewCell 中自定义 UIView 的 drawRect 行为错误

如何将自定义视图拖动为 Xcode 6 中自定义视图的私有属性

将 UIViewController 设置为 UITableViewCell 中自定义 UIView 的委托

在自定义 UIView 类 Iphone 上应用自动布局约束。

在 applozic 中自定义相机叠加层