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 をサブビューとして View Controller のビューに追加します。

于 2012-04-18T21:39:38.910 に答える