我为手指绘画应用程序创建了一个自定义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
我已设置了具有功能但无效的擦除按钮。
答案 0 :(得分:2)
你遇到的问题是你不应该在UIGraphicGetContext()
之外拨打drawRect:
在touchesBegan:withEvent:
和touchesMoved:withEvent:
中,您应该只是存储您想要绘制的点,并像现在一样调用[self setNeedsDisplay]
。
在drawRect:
实施中,您将绘制已存储的点数。
你可以看一下这个github repo,它提供了一个平滑绘图的实现:https://github.com/levinunnink/Smooth-Line-View
答案 1 :(得分:1)
最后我找到了解决方案。我的错误是我使用新的touchMove
在context
方法中实现了擦除代码。我不需要新的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];
}
我希望它能帮助有人擦除功能。