在iOS上,为什么UIBezierPath绘图不需要上下文?

时间:2012-05-19 19:27:30

标签: iphone ios uikit core-graphics

在iOS上,我们可以使用

drawRect中画一条线
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextBeginPath (context);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 100, 100);
CGContextStrokePath(context);

但如果我们删除上面的代码,我们也可以绘制一个矩形,只需使用:

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

两个相关问题:

1)为什么UIBezierPath不需要获取或使用当前上下文?

2)如果我有两个上下文怎么办?一个用于屏幕,一个是位图上下文,那么如何判断要为UIBezierPath绘制哪个上下文?我认为它可能是UIGraphicsSetCurrentContext但它不存在。

3 个答案:

答案 0 :(得分:22)

UIBezierPath确实使用了上下文。它使用当前的UIKit图形上下文。这与UIGraphicsGetCurrentContext()已经获得的完全相同。

如果您希望UIBezierPath使用其他上下文,则可以使用UIGraphicsPushContext(),但必须记得在完成后使用UIGraphicsPopContext()

答案 1 :(得分:6)

我认为提到CGContextFillRect比使用UIBezierPath要快8.5倍(如果性能是一个因素并假设您不需要使用UIBezierPath进行更复杂的绘图)可能会有用

我在Apple的HazardMap示例(http://developer.apple.com/library/ios/#samplecode/HazardMap/Introduction/Intro.html)中添加了一些时间,每个mm的时间以毫秒为单位~0.00064 ms / rect对于CGContextFillRect方法,对于UIBezierPath方法,对于~0.00543 ms / rect,可能是b / c,后者需要更多的消息传递开销。

即。我正在使用

进行比较
CGContextFillRect(ctx, boundaryCGRect);

与使用

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

在HazardMapView的内部循环中(加上上面提到的更改来推送/弹出传递给HazardMapView的上下文drawMapRect:zoomScale:inContext:)。

ETA

答案 2 :(得分:5)

  

在iOS上,我们可以使用

drawRect 中绘制一行

我强调了本声明的重要部分。在drawRect:内部,UIKit已经为您设置了一个上下文,任何基于对象的绘图指令都直接进入该上下文。 UIBezierPath确实正在使用该上下文,它不需要显式传递。

在Cocoa Touch中,必须始终有绘图上下文(在这种情况下,上下文最终会被绘制到屏幕上)。如果您不在drawRect:内,则必须自己创建一个上下文。

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

请注意,第一个函数调用是获取 CurrentContext()。当你使用CoreGraphics的功能绘图界面时,你需要将一个上下文传递给每个函数,但你不是在这里创建一个,你只是检索已经存在的那个。

Graphics contexts在堆栈中。如果你想绘制你创建的上下文,你可以使用UIGraphicsPushContext()将其推送到堆栈(正如Kevin已经提到的那样),然后回到上一个。