背景:我想在用户触摸某处时绘制块。如果块在那里,我想删除它。我使用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,..."
)中的值。当我实际使用它而没有重绘时,这将变得更有效。请坚持提问。谢谢。
答案 0 :(得分:1)
我没有在任何地方看到您实际清除之前绘制的内容。除非你明确清楚(例如填充UIRectFill()
- 除了填充显式路径之外,它是一种更方便的绘制矩形的方法),Quartz将只是绘制旧内容,这将在尝试擦除时会导致意外行为。
那么......如果你放在-drawRect:
的开头会发生什么:
[[UIColor whiteColor] setFill]; // Or whatever your background color is
UIRectFill([self bounds]);
(这当然是极其低效的,但根据你的评论,我无视这一事实。)
(另外,您可能应该将您的绘图代码包装在CGContextSaveGState()
/ CGContextRestoreGState()
对中,以避免污染任何调用代码的图形上下文。)
编辑:我总是忘记这个属性,因为我通常想要绘制更复杂的背景,但是你可以通过在UIView上设置clearsContextBeforeDrawing:YES
来获得类似的结果。
答案 1 :(得分:0)
这种方法对我来说似乎有点奇怪,因为每次调用touchesEnded方法时你需要重绘(这是一项昂贵的操作)并且还需要跟踪方块。我建议你继承一个UIView并实现drawRect:方法,这样视图就知道如何绘制自己并在视图控制器中实现touchesEnded方法,在那里你可以检查你是否触摸过squareView然后从视图控制器的视图中删除它,否则创建一个squareView并将其作为子视图添加到视图控制器的视图中。