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
工作正常。但是在绘图之前清除上下文:是
不起作用。这是非常低效的,但就我而言,它是完美的。非常感谢。