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

16

在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个回答

22

1
那么我们会使用 UIGraphicsPushContext(myBitmapContext); 来开始在位图上下文中绘制? - nonopolarity

7
我认为提到一下,CGContextFillRect比使用UIBezierPath快大约8.5倍,这可能会很有用(如果性能是一个因素,并且假设您不需要使用UIBezierPath进行更复杂的绘图)。我在苹果的HazardMap示例(http://developer.apple.com/library/ios/#samplecode/HazardMap/Introduction/Intro.html)中添加了一些时间计算,每个矩形的毫秒时间是约0.00064ms/rect对于CGContextFillRect方法,而对于UIBezierPath方法则是约0.00543ms/rect,可能是因为后者需要更多的消息传递开销。也就是说,我正在比较使用

CGContextFillRect(ctx, boundaryCGRect);

与使用相比

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

在HazardMapView的内循环中(加上上述更改以推送/弹出传递给HazardMapView drawMapRect:zoomScale:inContext:的上下文),请注意。
预计到达时间。

1
请注意,上述数字来自于在 Macbook Pro(2012 年早期版)上运行的 iPhone 6.0 模拟器。在实际的 iPad3 上运行此代码,CGContextFillRect 的速度似乎比使用 UIBezierPath 的方法快约 5.7 倍。当然,这取决于您使用的设备(优化设置似乎不会对此产生太大影响)。 - ETA

5
在iOS上,我们可以在drawRect:中使用绘制一条线。我已经强调了这个陈述的重要部分。UIKit已经为您设置了上下文,在drawRect:内部,任何基于对象的绘图指令都直接进入该上下文。确实是使用UIBezierPath来操作上下文,只是不需要显式传递上下文。
在Cocoa Touch中,必须始终存在一个绘图上下文(在本例中,该上下文最终将被绘制到屏幕上)。如果您不在drawRect:内部,则必须自己创建一个上下文。
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextBeginPath (context);
CGContextMoveToPoint(context, 0, 0);

请注意第一个函数调用是GetCurrentContext()。当您使用CoreGraphics的功能性绘图接口时,需要将上下文传递给每个函数,但您在此处没有创建上下文,而是检索已经存在的上下文。 图形上下文在堆栈中。如果要绘制到已创建的上下文中,则可以使用UIGraphicsPushContext()将其推送到堆栈中,然后返回到以前的上下文。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接