1 简介
本地渲染手段(也称为 Quartz)包括: Core Graphics, Core Animation 和 UIKit, 主要使用 CPU 完成运算, 其中 Core Graphics 是 Quartz 的核心技术. UIKit 绘制建立在 CG 基础上.
还有一种绘图手段: OpenGL. 主要使用 GPU 完成运算.
这里只对本地渲染绘制的技术进行介绍, 其中 Core Graphics 是主要工具, 来自苹果官方文档的 Drawing and Printing Guide for iOS.
首先要明确本地绘制的一些环境基础:
- 在 drawRect 中获取绘图上下文环境, 这个环境的当前配置可以保存和恢复.
- iOS 中的 UIKit 坐标系的原点在左上角, 并且使用的浮点 point 来表示屏幕坐标, 而不是像素.
Core Graphics(后面简称 CG框架) 是一种基于 path 概念的绘图系统. 在 UIKit 中提供了 CG 中一些接口的封装, 方便使用. CA 中提供的主要是对 UIView 属性的动画支持.
2 UIKit 图形系统
在 iOS 中, 任何绘图系统都是在 UIView 或是其子类对象上进行绘制的. 并且发生在 UIView 对应的一个绘图上下文(graphics context)中.
视图绘制周期如下:
- 视图首先在第一次显示的时候进行绘制, 绘制时调用的是
drawRect
方法, 然后将自己标记为已更新. - 直到外界调用
setNeedsDisplay
或setNeedsDisplayInRect
方法, 重新触发视图绘制, 在绘制的时候是调用的drawRect
方法.
绘图上下文就是绘制时候所处的一个环境, 可以在其中配置诸如 path 的线宽, 线条颜色等内容.
每个绘图上下文都有对应的坐标系, 而且对应有三个不同的坐标系:
iOS 中每个绘图框架都会根据当前绘图上下文建立默认坐标系, 不同点是 UIKit 和 CA 使用的是原点在左上角, CG 的默认坐标系原点在左下角:
但是当在 UIView 中使用 CG 进行绘制, 需要手动使用 UIGraphicsGetCurrentContext 获取绘图上下文, 而获取的这个上下文的默认坐标系是原点在左上角的(ULO). 当然也可以对该绘图上下文的坐标系进行翻转, 变为 CG 原始的 LLO 坐标系.
在 iOS 中使用逻辑坐标空间来描述位置, 其中的坐标以 point 为单位, 然后再经过一定运算映射到实际硬件上面, 故有一个主要原则: 即 point 和像素并非一一对应.
使用逻辑坐标空间的目的是描述屏幕上实体的相对大小和位置, 则映射到不同屏幕上的相对大小和位置也就是确定的了.
而映射的缩放倍数可以通过任何可获取的 contentScaleFactor 来读到.
CG 和 CA 以及 UIKit 都已经自动将映射关系考虑在内了, 故开发者只需关注逻辑坐标空间即可. 只是在有些时候, 比如要处理图片, 这时才要考虑缩放系数带来的影响.
绘图上下文是在 drawRect 方法被调用之前被 View 对象创建出来的. 并且只会在 drawRect 调用过程中存在.
当需要创建复杂路径时, 可以使用贝塞尔路径, 使用引导可以参考这篇文章.