免费开源的iOS开发学习平台

绘图CoreGraphics:1-基本概念

当一个视图View显示在屏幕上时,其展现给用户的样式都是经过系统绘制后显示在屏幕上的。例如,UILabel控件能够在控件所在矩形区域的中间/左侧/右侧显示文字,UIImageView可以显示一张图片,UIButton可以显示图片加文字,这些控件最终展示的效果其实都是经过绘图后才显示出来的,而绘图的过程可以由程序员自行控制。也正因为如此,我们可以去控制绘图的过程,从而可以使视图展示不同的效果。这就需要我们去学习CoreGraphics框架。

Quartz2D

CoreGraphics中最关键的部分是一个名为Quartz 2D的API集合,它包含了各种函数、数据类型以及对象,能够让大家在内存中直接绘制视图和图像。在使用CoreGraphics框架时,需要提前了解在绘图过程中涉及的几个重要概念。

  • 画布(page):Quartz 2D将正在进行绘制的视图视作一个虚拟的画布,在画布上用画笔画画,就必须遵循一定的规则,例如,绘制的内容是有先后顺序的,如下图所示。

  • 路径(Path):当你拿到一只画笔时,那么就能够随心所欲的在画纸上绘画,画笔移动的轨迹就是路径。如下图所示,一只粉红色的画笔绘制了两个图形,中间使用蓝色进行了填充。在UIKit框架中,有一个称为贝塞尔路径(UIBezierPath)的类专门用来设置各种样式的路径对象。

  • 绘图上下文(Graphics Context):绘图上下文,有时也称为绘图环境,绘图上下文中会保存绘图的信息和状态,并负责将图形绘制在视图上,即绘图的输出终端(Drawing Destination),Quartz提供了5种绘图的输出目标,如下图所示。例如,可以输出到窗口屏幕window,也可以输出到打印机printer,也可以保存为文件PDF等。但我们在开发中最经常使用的是layer,后续会详细介绍。

绘图原理

有关Quartz2D的绘图原理和我们日常生活中绘图是一致的。例如,我们拿出一张纸,以及一支笔,那么就可以使用这支笔在纸上画出各种线条(路径),线条的样式,例如:线条的粗细以及颜色,则取决于画笔;而路径则取决于绘画者的意愿。当线条或者图画之间有交叉或者覆盖时,最新绘画的内容会覆盖之前的内容。

使用Quartz2D进行图形绘制时,通常需要向图形所在的视图中添加绘图代码。比如创建一个UIView的子类,并向该类的drawRect:方法中添加Quartz函数的调用,重写系统默认的drawRect方法,相当于在系统原来的绘图基础上,再进行新的绘图。

注意一个特殊情况:UIImageView的子类不会调用drawRect方法。

绘图中经常使用的方法

在使用CoreGraphics框架对视图进行绘图操作时,UIView中如下的几个方法需要程序员重点关注,这涉及到绘图的时机。

  • drawRect:方法:当视图每次需要进行自身重新绘制时都会调用该方法,所以如果在drawRect:方法中插入视图绘制的代码,那么这段绘图代码就会起效,从而对视图进行重绘。该方法会被系统自动调用。
- (void)drawRect:(CGRect)rect;
  • setNeedDisplay方法:当手工调用这个方法时,会调用drawRect:方法进行绘图,但该方法是异步执行的,即不是立即调用drawRect:方法进行绘图,而是在屏幕每次刷新后才会调用。
- (void)setNeedsDisplay;