Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On iOS, why UIBezierPath drawing doesn't require a context?

On iOS, we can draw a line in drawRect using

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

but we can also draw a rectangle if we remove the above code, and just use:

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

Two related questions:

1) Why doesn't UIBezierPath need to get or use the current context?

2) What if I have two context: one for screen, and one is a bitmap context, then how to tell which context to draw to for UIBezierPath? I thought it might be UIGraphicsSetCurrentContext but it doesn't exist.

like image 427
nonopolarity Avatar asked May 19 '12 19:05

nonopolarity


2 Answers

UIBezierPath does use a context. It uses the current UIKit graphics context. This is exactly the same thing that you're already getting with UIGraphicsGetCurrentContext().

If you want UIBezierPath to use a different context you can use UIGraphicsPushContext(), but you have to remember to use UIGraphicsPopContext() when you're done.

like image 74
Lily Ballard Avatar answered Sep 23 '22 15:09

Lily Ballard


I thought it might be useful to mention that CGContextFillRect is ~8.5x faster than using a UIBezierPath from what I can tell (in case performance is a factor and assuming you don't need to use a UIBezierPath for more complex drawing).

I added some timing to Apple's HazardMap example (http://developer.apple.com/library/ios/#samplecode/HazardMap/Introduction/Intro.html) and the time in ms per rect is ~0.00064 ms/rect for the CGContextFillRect approach versus ~0.00543 ms/rect for the UIBezierPath approach, presumably b/c the latter requires more message passing overhead.

i.e. I'm comparing using

CGContextFillRect(ctx, boundaryCGRect);

versus using

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

in the inner loop in HazardMapView (plus the above-mentioned changes to push / pop the context that is passed to HazardMapView drawMapRect:zoomScale:inContext:).

ETA

like image 25
ETA Avatar answered Sep 21 '22 15:09

ETA