使用着色器制作渐变的方法与直接用Quartz提供的CGGradient方法类似:
1、首先创建色彩
2、创建一个函数对象。该对象包含了输入范围信息以及输出范围信息。
3、创建着色器对象。创建着色器对象时也指定了所要绘制矩形的起点坐标与终点坐标。
4、绘制
代码如下:
01 // 02 // MyQuartzView.m 03 // QuartzTest 04 // 05 // Created by zenny_chen on 12-2-21. 06 // Copyright (c) 2012年 GreenGames Studio. All rights reserved. 07 // 08 #import "MyQuartzView.h" 09 // Quartz2D以及Core Animation所需要的头文件 10 #import11 @implementation MyQuartzView 12 - (id)initWithFrame:(CGRect)frame 13 { 14 self = [super initWithFrame:frame]; 15 if (self) { 16 // Initialization code 17 } 18 return self; 19 } 20 static void MyShaderProcedure(void *info, const CGFloat *in, CGFloat *out) 21 { 22 CGFloat color; 23 if(in[0] < 0.33f) 24 color = 0.3f; 25 else if(in[0] < 0.66f) 26 color = 0.9f; 27 else 28 color = 0.6f; 29 out[0] = color; 30 out[1] = color; 31 out[2] = color; 32 out[3] = 1.0f; 33 } 34 // Only override drawRect: if you perform custom drawing. 35 // An empty implementation adversely affects performance during animation. 36 - (void)drawRect:(CGRect)rect 37 { 38 // Drawing code 39 // 创建Quartz上下文 40 CGContextRef context = UIGraphicsGetCurrentContext(); 41 const CGFunctionCallbacks callbacks = { 42 .version = 0, .evaluate = &MyShaderProcedure, .releaseInfo = NULL 43 }; 44 // 创建函数对象 45 CGFunctionRef funcRef = CGFunctionCreate(NULL, // 将info置空 46 1, // 1个输入元素(每个元素为2个分量来表示区间) 47 (CGFloat[]){ 0.0f, 1.0f}, 48 4, // 4个输出元素 49 (CGFloat[]){ 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 50 &callbacks); 51 // 创建色彩空间对象 52 CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 53 // 创建着色器对象 54 CGShadingRef shadingRef = CGShadingCreateAxial(colorSpaceRef, 55 CGPointMake(0.0f, 0.0f), // 起点坐标 56 CGPointMake(320.0f, 460.0f), // 终点坐标 57 funcRef, false, false); 58 // 释放色彩空间对象 59 CGColorSpaceRelease(colorSpaceRef); 60 // 释放函数对象 61 CGFunctionRelease(funcRef); 62 // 绘制着色渐变 63 CGContextDrawShading(context, shadingRef); 64 // 释放着色器对象 65 CGShadingRelease(shadingRef); 66 } 67 @end
从效果上我们可以看出,利用着色器做线性渐变仍然是以一个45度轴为基础进行渐变操作的。上述代码将产生一个从上到下的,暗灰、白到灰白的45度斜条。