Pattern
Pattern可翻译为样式、模型。类似于iOS中自定义的view,可以重复多次把自定义的view添加到控制器的view上。样式(Pattern)是绘制操作的一个序列,可以重复的绘制到一个图形上下文上。
样式单元格
样式单元格是样式的基本组件,在创建的时候就要定义单元格的边界,并在这个范围内进行绘制。在图形上下文上绘制单元格时,可以随意指定两个单元格之间上下左右间距,也可以指定负数,单元格重合而已。像极了添加view控件。
着色样式和模板样式
着色样式是有固定颜色的,在创建样式单元格的时候就指定其颜色了,跟绘制流程没有关系。
模板样式即为非着色样式,在创建样式单元格的时候只指定了形状,并没有指定颜色,在绘制过程中指定颜色。
在Quartz 2D中可以使用这两种样式实现样式绘图,将创建好的样式绘制到page上的过程称为平铺,有三种平铺选项:1、没有失真,2、最小的失真的恒定间距,3、恒定间距。
绘制着色样式
绘制着色样式一般需要下面几步:1、设置样式单元格的回调函数,2、设置着色模式单元格,3、绘制操作。下面是绘制着色样式的示例代码和运行结果:
|
|
运行结果:
代码解释:
上述代码块中第三个函数drawPattern
的作用就是第1步:设置样式单元格的回调函数。参数info
:是指向模式相关数据的指针,可以传NULL
。context
:是图形上下文。在该函数中指定了每个颜色块的大小和填充色。因为是着色样式,所以指定填充色。
第二个函数,也是在drawRect
方法中调用的函数clorePatternPaingting
,执行了第2步:设置着色模式单元格和第3步:绘制操作。下面对每块代码进行解释:
清空基本颜色空间:
|
|
因为我们要使用着色样式里面的颜色,所以清空基本颜色空间,以确保着色样式上的颜色能显示。可以试一下把这段代码注释的结果,绘制着色样式的空间为黑色,因为基本颜色空间没清空也没着色,所以呈黑色。
设置着色模式单元格:
|
|
模式单元格的信息保存在CGPatternRef
类型的CGPattern
对象中,使用CGPatternCreate
创建该对象。需要传入的参数依次解释为:
- info:是一个指针,指向我们要传递给绘制回调函数的数据。这里传的是
NULL
- bound:指定模式单元格的大小
- matrix:指定模式矩阵,它将模式坐标系统映射到图形上下文的默认坐标系统。如果希望两个坐标系统是一样的,则可以使用单位矩阵。
- xStep, yStep:指定单元格之间的水平和竖直间距。
- tiling:平铺模式,可以是kCGPatternTilingNoDistortion、kCGPatternTilingConstantSpacingMinimalDistortion、kCGPatternTilingConstantSpacing
- isColored:指定模式单元格是着色模式(true)还是模板模式(false)
- callbacks:是一个指向CGPatternCallbacks结构体的指针。格式如下:
|
|
version
一般设置为0
,drawPattern
是指向设置样式单元格的回调函数,releaseInfo
是指向回调函数,释放CGPattern对象时调用,以释放存储在我们传递给绘制回调的info参数中的数据。如果在这个参数中没有传递任何数据传NULL
。
所以CGPatternCallbacks
结构体定义为static const CGPatternCallbacks call = {0, &drawPattern, NULL};
绘制着色样式
|
|
调用函数CGContextSetFillPattern
使用着色样式进行填充操作,或者调用函数CGContextSetStrokePattern
进行描边操作。需要指定着色样式在填充或描边过程的透明度。
样式使用完毕后需要释放,调用函数:CGPatternRelease
将定义的着色样式使用函数CGContextFillRect
填充到指定rect
的矩形中。
这一系列操作都放到函数clorePatternPaingting
内,在drawRect
方法中直接调用该函数即可完成着色样式的定义和绘制。
绘制模板样式
绘制模板样式的步骤和绘制着色样式的一样:1、设置样式单元格的回调函数,2、设置模板模式单元格,3、绘制操作。下面是绘制模板样式的示例代码和运行结果:
|
|
运行结果:
代码解释参考上文中着色样式的代码解释。区别1是用下述代码设置样式单元格的颜色:
|
|
区别2是CGPatternCreate
函数中传的参数是false
。
阴影
阴影有三个属性:x偏移量,y偏移量,模糊度
阴影通过函数CGContextSetShadow
设置,指定图形上下文、x偏移量、y偏移量、模糊度。设置阴影后,绘制的对象都会有阴影,阴影的色值为0.3透明度的黑色,颜色RGBA值为{0, 0, 0, 0.3}。
也可以是使用函数CGContextSetShadowWithColor
设置彩色阴影。
在调用CGContextSetShadow
或CGContextSetShadowWithColor
之前保存图形状态,可以通过恢复图形状态来关闭阴影。或者设置阴影颜色为NULL
关闭阴影。
分别设置彩色阴影和普通阴影:
|
|
运行结果:
x偏移量正值在图形右边,负值在图形左边。y偏移量和坐标有关,在iOS中,UIKit坐标系y轴和Quartz 2D坐标系y轴相反,所以如果是由UIKit创建的图形上下文则正值在图形下面,负值在图形上面。macOS的坐标系和Quartz 2D坐标系一样,所以正值在图形上面,负值在图形下面。阴影绘制不受CTM影响。
渐变
可以使用函数CGShadingRef
和CGGradientRef
创建渐变。渐变分为轴向渐变和径向渐变。渐变的颜色变化有很多,可以是一种颜色到另一种颜色过度,也可以是多种颜色依次过度变化,还有是一种颜色的透明度alpha
变化,但是这种无法绘制到PDF上,无法打印。
CGShading
和CGGradient
的区别:
CGGradient | CGShading |
---|---|
可以使用同一对象绘制轴向和径向梯度 | 需要创建单独的对象的轴向和径向梯度 |
在绘图时设置渐变的几何体 | 在对象创建时间设置渐变的几何体 |
Quartz计算梯度中每个点的颜色 | 需要提供一个回调函数,用来计算渐变中每个点的颜色 |
可以定义两个以上的位置和颜色 | 需要设计回调,使用两个以上的位置和颜色 |
CGGradient
使用CGGradient创建渐变。
- 首先调用函数
CGGradientCreateWithColorComponents
创建CGGradient
对象,参数含义分别是:颜色空间、颜色数组(采用RGBA颜色)、位置数组(0.0-1.0之间的数值,0.0为轴线起点,1.0为轴线终点。传递NULL默认0为起始位置,1为终点位置,相当于{0.0, 1.0})、数组中元素个数。 - 调用
CGContextDrawLinearGradient
函数绘制轴向渐变或CGContextDrawRadialGradient
函数绘制径向渐变,参数含义分别是:图形上下文、CGGradient
对象、起始位置、终止位置、绘图选项。 - 绘制完毕后,释放颜色空间和
CGGradient
对象。
绘制轴向渐变:
|
|
绘制径向渐变:
|
|
CGShading
绘制轴向渐变需要以下步骤:
- 设置 CGFunction 对象来计算颜色值
- 创建轴向渐变的 CGShading 对象
- 裁减上下文
- 使用 CGShading 对象来绘制轴向渐变
- 释放对象
绘制轴向渐变完整代码:
|
|
运行结果:
绘制径向渐变,需要以下步骤:
- 设置 CGFunction 对象来计算颜色值
- 创建径向渐变的 CGShading 对象
- 使用 CGShading 对象来绘制径向渐变
- 释放对象
绘制径向渐变完整代码:
|
|
参考文章:南峰子翻译的Quartz2D编程指南