Iphone iOS:CGContextRef drawRect与输入不一致

Iphone iOS:CGContextRef drawRect与输入不一致,iphone,ios,drawrect,setneedsdisplay,cgcontextref,Iphone,Ios,Drawrect,Setneedsdisplay,Cgcontextref,背景:我想在用户触摸某处时画块。如果有块,我想把它抹掉。我使用NSMutableArray来管理块,以跟踪块应该到达的点。每次用户触摸时,它将确定触摸位置是否已包含块,并相应地管理阵列 问题:我收到了一个非常奇怪的反馈。首先,数组中的所有内容都按照我的要求工作。当用户想要擦除一个块时,问题就出现了。正确维护阵列时,图形似乎忽略了阵列中的更改。它只会删除最后一个点。甚至当用户点击其他地方时,闪光灯也会开关 以下是代码: - (void)drawRect:(CGRect)rect { NSL

背景:我想在用户触摸某处时画块。如果有块,我想把它抹掉。我使用
NSMutableArray
来管理块,以跟踪块应该到达的点。每次用户触摸时,它将确定触摸位置是否已包含块,并相应地管理阵列

问题:我收到了一个非常奇怪的反馈。首先,数组中的所有内容都按照我的要求工作。当用户想要擦除一个块时,问题就出现了。正确维护阵列时,图形似乎忽略了阵列中的更改。它只会删除最后一个点。甚至当用户点击其他地方时,闪光灯也会开关

以下是代码

- (void)drawRect:(CGRect)rect
{
    NSLog(@"drawrect current array %@",pointArray);
    for (NSValue *pointValue in pointArray){
        CGPoint point = [pointValue CGPointValue];
        [self drawSquareAt:point];
    }
} 

- (void) drawSquareAt:(CGPoint) point{
    float x = point.x * scale;
    float y = point.y * scale; 

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextMoveToPoint(context, x, y);
    CGContextAddLineToPoint(context, x+scale, y);
    CGContextAddLineToPoint(context, x+scale, y+scale);
    CGContextAddLineToPoint(context, x, y+scale);
    CGContextAddLineToPoint(context, x, y);

    CGContextSetFillColorWithColor(context, [UIColor darkGrayColor].CGColor);
    CGContextFillPath(context);
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *aTouch = [touches anyObject];
    CGPoint point = [aTouch locationInView:self];
    point = CGPointMake( (int) (point.x/scale), (int) (point.y/scale));
    NSLog(@"Touched at %@", [NSArray arrayWithObject: [NSValue valueWithCGPoint:point]]);

    NSValue *pointValue = [NSValue valueWithCGPoint:point];
    int i = [pointArray indexOfObject:pointValue];
    NSLog(@"Index at %i",i);
    if (i < [pointArray count]){
        [pointArray removeObjectAtIndex:i];
        NSLog(@"remove");
    }else {
        [pointArray addObject:pointValue];
        NSLog(@"add");
    }
    NSLog(@"Current array : %@", pointArray);

    [self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect
{
NSLog(@“drawrect当前数组%@”,pointArray);
用于(NSValue*点数组中的点值){
CGPoint point=[pointValue CGPointValue];
[在:点上的自我描述];
}
} 
-(空)drawSquareAt:(CGPoint)点{
浮动x=点x*比例;
浮动y=点y*刻度;
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextMoveToPoint(上下文,x,y);
CGContextAddLineToPoint(上下文,x+比例,y);
CGContextAddLineToPoint(上下文,x+比例,y+比例);
CGContextAddLineToPoint(上下文、x、y+比例);
CGContextAddLineToPoint(上下文,x,y);
CGContextSetFillColorWithColor(上下文[UIColor darkGrayColor].CGColor);
CGContextFillPath(上下文);
}
-(void)touchesend:(NSSet*)toucheevent:(UIEvent*)event
{
UITouch*aTouch=[触摸任何对象];
CGPoint point=[aTouch locationInView:self];
点=CGPointMake((int)(点x/标度),(int)(点y/标度));
NSLog(@“触碰%@,[NSArray arrayWithObject:[NSValue VALUE WITHCGPOINT:point]]);
NSValue*pointValue=[NSValue valueWithCGPoint:point];
int i=[pointArray indexOfObject:pointValue];
NSLog(@“索引位于%i”,i);
如果(i<[点阵列计数]){
[pointArray removeObjectAtIndex:i];
NSLog(@“删除”);
}否则{
[pointArray addObject:pointValue];
NSLog(@“添加”);
}
NSLog(@“当前数组:%@”,点数组);
[自我设置需要显示];
}
比例
定义为16。
pointArray
是视图的成员变量

测试:您可以将其放入任何UIView中,并将其添加到viewController中以查看效果

问题:如何使图纸与阵列一致



更新+解释:我知道这种方法的成本,但它只是为我提供一个快速的数字。它不会在实际应用中使用,因此,请不要担心它有多贵。我创建此功能只是为了在我绘制的图形的
NSString
@“1,3,5,1,2,6,2,5,5,…”
)中获取一个值。当我实际使用它而无需重新绘制时,这将变得更加有效。请坚持提问。谢谢。

这种方法对我来说似乎有点奇怪,因为每次调用touchesend方法时,都需要重新绘制(这是一个昂贵的操作),还需要跟踪正方形。我建议您将UIView子类化并实现drawRect:方法,这样视图就知道如何绘制自己并在视图控制器中实现touchSended方法,您可以检查是否接触了squareView,然后将其从视图控制器的视图中删除,否则创建squareView并将其作为子视图添加到视图控制器的视图中。

我看不到任何地方您实际上正在清除之前绘制的内容。除非您明确清除(例如通过填充
UIRectFill()
——这是一种比填充显式路径更方便的绘制矩形的方法),否则Quartz将只绘制旧内容,这将在尝试擦除时导致意外行为

所以。。。如果在
-drawRect:
的开头放置,会发生什么情况:

[[UIColor whiteColor] setFill]; // Or whatever your background color is
UIRectFill([self bounds]);
(这当然是极其低效的,但根据你的评论,我忽略了这一事实。)

(另外,您可能应该将图形代码包装在
CGContextSaveGState()
/
CGContextRestoreGState()
对中,以避免污染任何调用代码的图形上下文。)


编辑:我总是忘记这个属性,因为我通常希望绘制更复杂的背景,但通过在UIView上设置
ClearContextBeforeDrawing:YES
,您可能会获得类似的结果。

谢谢您的关注。如果你知道我实际问题的答案,请提供帮助。请看我上面的更新回复。您的
setFill
工作正常。但是
在绘图之前清除上下文:是
不起作用。这是非常低效的,但就我而言,它是完美的。非常感谢。