如何在iPhone中的Custom UIView上擦除手指画

时间:2012-06-21 06:17:05

标签: iphone objective-c cgcontext paint cgcontextref

我为手指绘画应用程序创建了一个自定义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

我已设置了具有功能但无效的擦除按钮。

2 个答案:

答案 0 :(得分:2)

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

touchesBegan:withEvent:touchesMoved:withEvent:中,您应该只是存储您想要绘制的点,并像现在一样调用[self setNeedsDisplay]。 在drawRect:实施中,您将绘制已存储的点数。

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

答案 1 :(得分:1)

最后我找到了解决方案。我的错误是我使用新的touchMovecontext方法中实现了擦除代码。我不需要新的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];
}

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