2

タッチ座標を中心に円を描くようにアプリを作成したいと考えています。

これが私が今持っているコードです。確かにめちゃくちゃです。物事を描いたり、コンテキストを操作したりする練習はありません。ここで何が欠けていますか?前もって感謝します。

ビュー コントローラーは UIViewController のサブクラスです

@implementation ViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];
}

- (void)viewDidUnload
{
[super viewDidUnload];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *theTouch = [touches anyObject];

[self doSomething];

//[self.view setNeedsDisplay];

}

- (void) drawCircleAtPoint:(CGPoint)point withRadius:(CGFloat)radius inContext:(CGContextRef)context{
UIGraphicsPushContext(context);
CGContextBeginPath(context);
CGContextAddArc(context, point.x, point.y, radius, 0, 2*M_PI, YES);
CGContextFillPath(context);
UIGraphicsPopContext();
}

- (void)drawRect:(CGRect)rect
{
CGPoint point;
CGContextRef context = UIGraphicsGetCurrentContext();
point.x = self.view.bounds.origin.x + self.view.bounds.size.width/2;
point.y = self.view.bounds.origin.y + self.view.bounds.size.height/2;
CGContextSetLineWidth(context, 5.0);
[[UIColor whiteColor] setFill];
[self drawCircleAtPoint:point withRadius:50 inContext:context];

}

@end

ここでは、少なくとも画面の中央に円を描画したかったのですが、これでもできません。

4

2 に答える 2

4

drawRect は UIView クラスのメソッドです。 ViewController では使用できないため、呼び出されません。

理想的には、UIView サブクラスに drawRect と drawCircleAtPoint を配置する必要があります。また、そのビュー クラスに touches メソッドを追加します。DrawCircleView などと呼ぶことができます。

このカスタム ビューのオブジェクトを作成し、サブビューとして viewDidLoad のビュー コントローラーのビューに追加します。

touches メソッドで setNeedsDisplay を呼び出し、touvh のポイントを CGPoint インスタンス変数に格納し、drawRect でアクセスします。

アップデート

以前に描いた円を保存することができます。

多くの可能性があります。あなたに最も適したものを選択してください。それぞれについて詳細な説明はしませんでしたが、十分な情報を提供しました。

  • 円を編集可能にしたい場合は、中心と半径に関する円情報をNSMutableArray の 1 つのオブジェクトとして追加し続ける必要があります。drawRect の最初に、それらすべてをループで再描画する必要があります。

    実際、CGPath を使用、そのパスに円を追加し続け、cgcontext へのパスを drawRect に追加し、CGPath をインスタンス変数として保持して、最後の drawRect 呼び出しからの以前の情報を保持することをお勧めします。ただし、別の色で円を描画できるようにしたい場合は、それらを異なる CGPath に配置する必要があります。これらの CGPath をオブジェクトの色情報とともに変更可能な配列に再度追加できます。

また

  • これらの円をすべて保存して再描画すると、配列が大きくなり続けるとパフォーマンスが低下します。元に戻す機能が必要ない場合、または以前のサークルを編集したくない場合。次に、drawRect の最後に描画されたものを imageData として保存し、それをインスタンス var として保持し、drawRect が呼び出されるたびに再描画し、その上に円を描画して、同じインスタンスに画像を再度保存します。

例: drawRect の最後で、画面の画像をインスタンス変数 _savedImage に保存できます。

  _savedImage = UIGraphicsGetImageFromCurrentImageContext(); 

そして、drawRect の先頭で再描画中に、_savedImageが nil でない場合、

 [_savedImage drawInRect:rect];

次に、タップしたポイントの周りに円を描くことができます。また、必要に応じて、いつでも図面を実際の画像ファイルに保存できます。

 NSData *imageData = UIImagePNGRepresentation(_savedImage);
[imageData writeToFile:@"imageName.png"];

また

  • 必要に応じて探索できますCGContextSaveGState() and CGContextRestoreGState() 。これらは、コンテキストをそれぞれスタックにプッシュおよびポップするために使用されます。したがって、最後のコンテキストを取得して再描画し、復元と保存の間に円を描くことができます。同じ上のこのstackOverflowの投稿をチェックしてください:CGContextの保存と復元
于 2012-05-24T19:02:51.283 に答える
3

drawRect のメソッド呼び出しは、 UIViewControllerではなくUIViewで発生します。 UIViewController はビューを管理し、委譲やその他の関連項目自体を処理します。描画は、viewController の view プロパティで行われます。

あなたの場合、次のことをしたいと思うでしょう:

  1. そこに実装された drawRect および drawCircle メソッドを使用して、独自のビューで UIView をサブクラス化します。
  2. XIB のデフォルトの UIView を独自のクラスに置き換えます (IB -> Identity Inspector -> Custom Class)
  3. イベントをフックして指のタッチを検出し、[view setNeedsDisplay] を使用して強制的に更新します。

注: UIImageView の drawRect のサブクラス化とオーバーライドは何もしません - それは特別に処理されます:

UIImageView クラスは、その画像をディスプレイに描画するように最適化されています。UIImageView は drawRect: サブクラスを呼び出しません。サブクラスにカスタム描画コードが必要な場合は、UIView を基本クラスとして使用することをお勧めします。

于 2012-05-24T19:00:53.963 に答える