2012-05-19 11 views
11

、我々はiOSでは、なぜUIBezierPathの描画にコンテキストが必要ないのですか? iOSの上で

CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextBeginPath (context); 
CGContextMoveToPoint(context, 0, 0); 
CGContextAddLineToPoint(context, 100, 100); 
CGContextStrokePath(context); 

を使用してdrawRectに線を引くことができますが、我々は上記のコードを削除し、ちょうど使用している場合、我々はまた、四角形を描画することができます

UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 100, 100)]; 
[path stroke]; 

2つの関連質問:

1)UIBezierPathは現在のコンテキストを取得する必要がありますか?

2)コンテキストが2つある場合:1つは画面用、もう1つはビットマップコンテキストで、次にどのコンテキストを描画するかを指定する方法はUIBezierPathですか?私はそれがUIGraphicsSetCurrentContextかもしれないと思ったが、それは存在しない。

答えて

22

UIBezierPathはコンテキストを使用します。現在のUIKitグラフィックスコンテキストを使用します。これは、あなたがすでにUIGraphicsGetCurrentContext()で取得しているのとまったく同じことです。

UIBezierPathに別のコンテキストを使用する場合は、UIGraphicsPushContext()を使用できますが、完了したらUIGraphicsPopContext()を覚えておく必要があります。 iOSの上で

+1

ので、我々は 'UIGraphicsPushContext(myBitmapContext)を使用します;'ビットマップコンテキストに描画を開始するには? –

+2

@動力能量:それは正しい –

5

、私たちは、私はこの声明の重要な部分を強調してきた

を使用してdrawRectにラインを描くことができます。 drawRect:の中には、UIKitによってコンテキストがすでに設定されており、オブジェクトベースの描画命令がそのコンテキストに直接入ります。 UIBezierPathは実際にそのコンテキストを使用しているだけで、明示的に渡す必要はありません。

ココアタッチでは、常に描画コンテキストが必要です(この場合、コンテキストは最終的に画面に描画されます)。 drawRect:の中にいない場合は、自分でコンテキストを作成する必要があります。

CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextBeginPath (context); 
CGContextMoveToPoint(context, 0, 0); 

最初の関数呼び出しがCurrentContext()を取得であることに注意してください。 CoreGraphicsの機能描画インタフェースを使用しているときは、各関数にコンテキストを渡す必要がありますが、ここでは作成していません。既に存在するコンテキストを取得するだけです。

Graphics contextsがスタックしています。あなたが作成したコンテキストに描画したい場合は、UIGraphicsPushContext()(Kevinがすでに述べたように)を使ってスタックにプッシュし、前のコンテキストにポップバックします。

6

私は、CGContextFillRectが、私が知ることができるものからUIBezierPathを使用するよりも8.5倍速いことを言及することは有益だろうと思っていました。(パフォーマンスが重要な場合、より複雑な描画にUIBezierPathを使用する必要がない)。

AppleのHazardMapの例(http://developer.apple.com/library/ios/#samplecode/HazardMap/Introduction/Intro.html)にタイミングを追加し、1 rectあたりの時間は〜0.00064 ms/UIBezierPathアプローチではCGContextFillRectアプローチでは〜0.00543ms/rectであり、おそらくはb/cであればメッセージのオーバーヘッドが増えます。

すなわちzoomScale:私はHazardMapView drawMapRectに渡されるコンテキストをポップ/プッシュするHazardMapViewにおける内部ループ(プラス上記の変更で

UIBezierPath* path = [UIBezierPath bezierPathWithRect:boundaryCGRect]; 
[path fill]; 

を使用して対

CGContextFillRect(ctx, boundaryCGRect); 

を使用して比較していますinContext :)。

ETA

+1

上記の数値はMacBook Pro(2012年初め)で動作するiPhone 6.0シミュレータの数値です。これを実際のiPad3で実行すると、CGContextFillRectはUIBezierPathアプローチよりも5.7倍高速です。もちろんYMMVは使用しているデバイスによって異なります(最適化の設定はこれにあまり影響しないようです)。 – ETA