0

背景:当用户触摸某处时,我想绘制块。如果块在那里,我想擦除它。我通过使用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];
}

scale定义为 16. pointArray是视图的成员变量。

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

问题:如何让绘图与数组一致?


更新 + 说明:我知道这种方法的成本,但它只是为我创建一个快速的数字。它不会在实际应用中使用,因此,请不要挂断它的价格。我创建此功能只是为了在我绘制的图形的NSString( ) 中获取值。@"1,3,5,1,2,6,2,5,5,..."当我实际使用它而不重绘时,这将变得更有效率。请坚持提出的问题。谢谢你。

4

2 回答 2

1

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

所以......如果你放在开头会发生什么-drawRect:

[[UIColor whiteColor] setFill]; // Or whatever your background color is
UIRectFill([self bounds]);

(这当然是非常低效的,但是根据您的评论,我无视这一事实。)

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

编辑:我总是忘记这个属性,因为我通常想绘制更复杂的背景,但你可以通过clearsContextBeforeDrawing:YES在 UIView 上进行设置来获得类似的结果。

于 2012-04-18T21:59:10.033 回答
0

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

于 2012-04-18T21:39:38.910 回答