UIKit简化了创建和管理上下文的任务。建立一个新的图像或PDF上下文只需要一行,另一行进行包装结束上下文。在这些行之间,您可以自由地执行任何绘图请求。这些都将被应用于当前的上下文。
清单 1-6 使用与清单 1-5 相同的绘图函数,并产生相同的图像结果。但是,这些更新不是绘制到自定义的Quartz上下文,而是绘制到一个新建立的图像上下文。为了在Quartz和UIKit之间进行桥接,调用UIGraphicsGetCurrentContext()
,这会返回一个CGContextRef
类型的对象,使您可以在Core Graphics绘图调用中使用该值。
需要指出的是,当您将清单 1-6 中的代码行数与清单 1-4 和 1-5 的组合进行比较时,您会看到使用UIKit绘图更简单。
清单 1-6 使用UIKit中图像上下文绘制一个椭圆
1 | // Establish the image context |
你可以在启动任何图像或PDF上下文后调用UIGraphicsGetCurrentContext()
。 这个上下文会一直持续到你调用UIGraphicsEndImageContext()
或UIGraphicsEndPDFContext()
。
类似地,你可以通过调用UIGraphicsPushContext(context)
在这些例程之外建立一个上下文。清单 1-4 中提供了一个手动构建的Quartz上下文的范例,并用UIGraphicsPopContext()
结束这个上下文。这些调用都会在UIKit上下文堆栈中建立你正在绘制的上下文。压栈和出栈可以根据需要临时在绘制目标之间切换。
否则,在显式上下文环境之外,当前上下文是nil,有一个例外:在调用drawRect:
方法时,视图将上下文压入UIKit图形上下文栈中。因此,如果你正在实现drawRect:
方法,你可以假设总是有一个有效的上下文供你使用:
1 | - (void) drawRect: (CGRect) rect{ |
UIKit当前上下文
在Quartz中,几乎每个绘图函数都需要一个上下文参数。你需要明确地将上下文参数传递给每个函数。例如,你可能想设置画笔颜色为灰色:
1 | CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor); |
在UIKit绘图中,上下文是从运行时条件下建立的。如清单1-7。此代码再次构建了如图1-5所示的相同的4像素宽的椭圆形。然而,这个代码并没有明确地引用上下文。
此代码清单创建一个椭圆路径。它将线宽设置为4,将描边颜色设为灰色,然后描绘路径。 在每个步骤中,以您的名义访问上下文。与清单 1-6 一样,相同的灰色应用于当前上下文,但并未指定上下文。如下清单 1-7 没有提到上下文。
清单 1-7 使用UIKit图形上下文绘制椭圆
1 | // Stroke an ellipse using a Bezier path |
UIKit拥有一个图形上下文栈。它将绘制操作应用于该栈顶部的任何上下文。即:将最顶层上下文状态线宽更新为4和描边颜色更新为灰色。
那么如何将Core Graphics上下文与UIKit集成?UIKit提供了两个关键功能,本章前面已经简要提到:
- 通过调用
UIGraphicsPushContext(context)
手动push上下文。此函数将上下文压入到UIKit栈顶,并设置要绘制的活动上下文。 - 通过调用
UIGraphicsPopContext()
来保持栈的平衡。这会将当前上下文从UIKit堆栈中弹出,将活动上下文重置为堆栈中的下一个项目或将其重置为nil。
通过使用这些调用,可以将清单 1-7 中的基于Bezier路径的绘图代码嵌入到清单 1-3 中的基于Quartz的上下文中。这种方法将UIKit绘图连接到了Core Graphics上下文中创建和管理。
总而言之,将Core Graphics上下文与UIKit绘图混合的步骤如下:
- 创建一个Core Graphics上下文。
- 使用
UIGraphicsPushContext()
将上下文压入栈中。 - 使用可以推断当前上下文的UIKit绘图调用和显式使用上下文的Quartz调用组合。
- (可选地,将上下文内容检索生成图像。)
- 使用
UIGraphicsPopContext()
将上下文出栈。 - 释放上下文的内存空间。
如果您尝试在没有活动上下文的情况下使用UIKit绘制,您会收到警告,上下文无效。
本文翻译自《iOS Drawing Practical UIKit Solutions》作者:Erica Sadun,翻译:Cheng Dong。如果觉得本书不错请购买支持正版:亚马逊购买传送门,本书所有源代码可在GitHub上下载。译者虽然力求做到信,达,雅,但是由于时间仓促加之译者水平十分有限,文中难免会出现不正确,不准确,词不达意,难于理解的地方,还望各位批评指正,共同进步,谢谢。转载请注明出处。