【问题标题】:On iOS, why UIBezierPath drawing doesn't require a context?在 iOS 上,为什么 UIBezierPath 绘图不需要上下文?
【发布时间】:2012-05-19 19:27:30
【问题描述】:

在 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,但它不存在。

【问题讨论】:

    标签: iphone ios uikit core-graphics


    【解决方案1】:

    UIBezierPath 确实使用了上下文。它使用当前的 UIKit 图形上下文。这与您使用 UIGraphicsGetCurrentContext() 得到的完全一样。

    如果您希望UIBezierPath 使用不同的上下文,您可以使用UIGraphicsPushContext(),但您必须记住在完成后使用UIGraphicsPopContext()

    【讨论】:

    • 所以我们将使用UIGraphicsPushContext(myBitmapContext); 在位图上下文中开始绘制?
    【解决方案2】:

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

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

    即我正在比较使用

    CGContextFillRect(ctx, boundaryCGRect);
    

    相对于使用

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

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

    预计到达时间

    【讨论】:

    • 请注意,以上数字来自在 Macbook Pro 上运行的 iPhone 6.0 模拟器(2012 年初)。在实际的 iPad3 CGContextFillRect 上运行它似乎比使用 UIBezierPath 方法快约 5.7 倍。 YMMV 当然取决于您使用的设备(优化设置似乎对此影响不大)。
    【解决方案3】:

    在 iOS 上,我们可以使用

    drawRect中画一条线

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

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

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

    请注意,第一个函数调用是 GetCurrentContext()。当您使用 CoreGraphics 的函数式绘图接口时,您需要将上下文传递给每个函数,但您不是在此处创建一个,您只是在检索已经存在的一个。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多