之前我们设置过填充色,但是纯色的填充色略显单调,我们可以使用更加绚丽的填充模式,渐变填充以及模式填充
渐变填充
渐变有两种:线性渐变以及圆形渐变
线性渐变
- (void)drawRect:(CGRect)rect { //获取图像上下文对象 CGContextRef context = UIGraphicsGetCurrentContext(); //使用RGB模式的颜色空间(在Quartz 2D中凡是使用带有Create或者Copy关键字方法创建的对象,在使用后一定要使用对应的方法释放) CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); //颜色空间,如果使用了RGB颜色空间则4个数字一组表示一个颜色,下面的数组表示3个颜色 CGFloat colors[] = {1,1,0,1,0,1,1,1,1,0,1,0}; //locations代表3个颜色的分布区域(0~1),如果需要均匀分布只需要传入NULL CGFloat locations[3]={0,0.3,1}; CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 3); //需要释放颜色空间 CGColorSpaceRelease(colorSpace); //第三个参数表示起始点,第四个参数表示结束点 //最后一个参数如果设置kCGGradientDrawsAfterEndLocation表示结束点后面的区域使用渐变填充,设置kCGGradientDrawsBeforeStartLocation表示起始点前面的区域使用渐变填充,设置为0表示只填充起始点和结束点之间的区域 CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 100), CGPointMake(0, 150), 0);
CGGradientRelease(gradient);
}
圆形渐变
- (void)drawRect:(CGRect)rect { //获取图像上下文对象 CGContextRef context = UIGraphicsGetCurrentContext(); //使用RGB模式的颜色空间 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); //颜色空间,如果使用了RGB颜色空间则4个数字一组表示一个颜色,下面的数组表示3个颜色 CGFloat colors[] = {1,1,0,1,0,1,1,1,1,0,1,0}; //locations代表3个颜色的分布区域(0~1),如果需要均匀分布只需要传入NULL CGFloat locations[3]={0,0.3,1}; CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 3); //需要释放颜色空间 CGColorSpaceRelease(colorSpace); //第三个参数表示起始中心点,第四个参数表示起始半径 //第五个参数表示结束中心点,第六个参数表示结束半径 //最后一个参数如果设置kCGGradientDrawsAfterEndLocation表示结束点后面的区域使用渐变填充,设置kCGGradientDrawsBeforeStartLocation表示起始点前面的区域使用渐变填充,设置为0表示只填充起始点和结束点之间的区域 CGContextDrawRadialGradient(context, gradient, CGPointMake(160, 300), 50, CGPointMake(160, 300), 100, 0); }
使用渐变色填充
- (void)drawRect:(CGRect)rect { //获取图像上下文对象 CGContextRef context = UIGraphicsGetCurrentContext(); UIRectClip(CGRectMake(20, 20, 250, 250)); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGFloat colors[] = {1,1,0,1,0,1,1,1,1,0,1,0}; CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 3); CGColorSpaceRelease(colorSpace); CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 0), CGPointMake(300, 300), kCGGradientDrawsAfterEndLocation); }
模式填充
模式填充有两种:有颜色填充以及无颜色填充
有颜色填充的主要步骤如下
1:创建一个符合CGPatternDrawPatternCallback(void *,CGContextRef)签名的方法函数生产用来填充的瓷砖
2:使用CGPatternCreate创建CGPatterRef
3:使用CGColorSpaceCreatePattern创建颜色空间CGColorSpaceRef,这个颜色空间跟前面绘制渐变的颜色空间不太一样,前面创建渐变使用的颜色空间是设备无关的,我们需要基于这个颜色空间创建一个颜色空间专门用于填充(注意对于有颜色填充创建填充颜色空间参数为NULL,不用基于设备无关的颜色空间创建)
4:使用CGPatternRef和CGColorSpaceRef,通过CGColorCreateWitPattern创建填充颜色CGColorRef
5:将填充色设置为之前获得的CGColorRef然后进行绘制
void drawTile(void *info,CGContextRef context) { CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor); CGContextFillRect(context, CGRectMake(0, 0, 30, 30)); CGContextSetFillColorWithColor(context, [UIColor grayColor].CGColor); CGContextFillRect(context, CGRectMake(0, 30, 30, 30)); CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor); CGContextFillRect(context, CGRectMake(30, 0, 30, 30)); CGContextSetFillColorWithColor(context, [UIColor purpleColor].CGColor); CGContextFillRect(context, CGRectMake(30, 30, 30, 30)); } - (void)drawRect:(CGRect)rect { //获取图像上下文对象 CGContextRef context = UIGraphicsGetCurrentContext(); //填充模式回调函数结构体 CGPatternCallbacks callback = {0,drawTile,NULL}; //设置砖块样式 //void *infoCGRect 瓷砖绘制函数的第一个参数 //bounds 每块瓷砖的大小 //CGAffineTransform matrix 变换矩阵,如果不用变换可以传入CGAffineTransformIdentity //CGFloat xStep, CGFloat yStep 指定瓷砖块横向和纵向的间距,如果大于瓷砖大小,瓷砖间会有间隙 // CGPatternTiling tiling 平铺模式 //bool isColored 是否指定了颜色 //const CGPatternCallbacks *callbacks 回调函数结构体 CGPatternRef pattern = CGPatternCreate(NULL, CGRectMake(0, 0, 60, 60), CGAffineTransformMakeRotation(-45 * M_PI/180), 60, 60, kCGPatternTilingNoDistortion, true, &callback); //设置颜色空间 //设备无关的颜色空间 CGColorSpaceCreateDeviceRGB(); //模式填充颜色空间,注意对于有颜色填充模式,这里传NULL CGColorSpaceRef colorSpace = CGColorSpaceCreatePattern(NULL); //通过前两项设置颜色 CGFloat alpha = 1; CGColorRef color = CGColorCreateWithPattern(colorSpace, pattern, &alpha); CGColorSpaceRelease(colorSpace); CGPatternRelease(pattern); //绘制 CGContextSetFillColorWithColor(context, color); CGContextFillRect(context, CGRectMake(0, 20, 155, 155)); CGContextSetStrokeColorWithColor(context, color); CGContextStrokeRectWithWidth(context, CGRectMake(165,20, 155, 155), 5); }
也可以不创建CGColorRef,直接使用CGPatternRef和CGColorSpaceRef来进行有颜色填充
void drawTile(void *info,CGContextRef context) { CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor); CGContextFillRect(context, CGRectMake(0, 0, 30, 30)); CGContextSetFillColorWithColor(context, [UIColor grayColor].CGColor); CGContextFillRect(context, CGRectMake(0, 30, 30, 30)); CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor); CGContextFillRect(context, CGRectMake(30, 0, 30, 30)); CGContextSetFillColorWithColor(context, [UIColor purpleColor].CGColor); CGContextFillRect(context, CGRectMake(30, 30, 30, 30)); } - (void)drawRect:(CGRect)rect { //获取图像上下文对象 CGContextRef context = UIGraphicsGetCurrentContext(); //填充模式回调函数结构体 CGPatternCallbacks callback = {0,drawTile,NULL}; //设置砖块样式 //void *infoCGRect 瓷砖绘制函数的第一个参数 //bounds 每块瓷砖的大小 //CGAffineTransform matrix 变换矩阵,如果不用变换可以传入CGAffineTransformIdentity //CGFloat xStep, CGFloat yStep 指定瓷砖块横向和纵向的间距,如果大于瓷砖大小,瓷砖间会有间隙 // CGPatternTiling tiling 平铺模式 //bool isColored 是否指定了颜色 //const CGPatternCallbacks *callbacks 回调函数结构体 CGPatternRef pattern = CGPatternCreate(NULL, CGRectMake(0, 0, 60, 60), CGAffineTransformMakeRotation(-45 * M_PI/180), 60, 60, kCGPatternTilingNoDistortion, true, &callback); //设置颜色空间 //设备无关的颜色空间 CGColorSpaceCreateDeviceRGB(); //模式填充颜色空间,注意对于有颜色填充模式,这里传NULL CGColorSpaceRef colorSpace = CGColorSpaceCreatePattern(NULL); CGContextSetFillColorSpace(context, colorSpace); CGContextSetStrokeColorSpace(context, colorSpace); float alpha = 1; ////最后一个参数对于有颜色瓷砖指定为透明度的参数地址,对于无颜色瓷砖则指定当前颜色空间对应的颜色数组 CGContextSetFillPattern(context, pattern, &alpha); CGContextSetStrokePattern(context, pattern, &alpha); //绘制 CGContextFillRect(context, CGRectMake(0, 20, 155, 155)); CGContextStrokeRectWithWidth(context, CGRectMake(165,20, 155, 155), 5); }
结果和前一个例子一样
以上两个例子都是有颜色填充,在创建瓷砖的同时已经确定了瓷砖的样色,我们也可以创建瓷砖时只设定瓷砖的形状而不设置瓷砖的颜色,当使用瓷砖填充时再设定颜色
void drawTile(void *info,CGContextRef context) { CGContextFillRect(context, CGRectMake(0, 0, 30, 30)); CGContextFillRect(context, CGRectMake(30, 30, 30, 30)); } - (void)drawRect:(CGRect)rect { //获取图像上下文对象 CGContextRef context = UIGraphicsGetCurrentContext(); //填充模式回调函数结构体 CGPatternCallbacks callback = {0,drawTile,NULL}; //设置砖块样式 //void *infoCGRect 瓷砖绘制函数的第一个参数 //bounds 每块瓷砖的大小 //CGAffineTransform matrix 变换矩阵,如果不用变换可以传入CGAffineTransformIdentity //CGFloat xStep, CGFloat yStep 指定瓷砖块横向和纵向的间距,如果大于瓷砖大小,瓷砖间会有间隙 // CGPatternTiling tiling 平铺模式 //bool isColored 是否指定了颜色 //const CGPatternCallbacks *callbacks 回调函数结构体 CGPatternRef pattern = CGPatternCreate(NULL, CGRectMake(0, 0, 60, 60), CGAffineTransformIdentity, 60, 60, kCGPatternTilingNoDistortion, false, &callback); //设备无关的颜色空间 CGColorSpaceRef baseColorSpace = CGColorSpaceCreateDeviceRGB(); //模式填充颜色空间 CGColorSpaceRef colorSpace = CGColorSpaceCreatePattern(baseColorSpace); CGContextSetFillColorSpace(context, colorSpace); CGContextSetStrokeColorSpace(context, colorSpace); CGFloat components[]={250/255.0,100/255.0,150/255.0,1.0}; ////最后一个参数对于无颜色填充模式指定为当前颜色空间颜色数据 CGContextSetFillPattern(context, pattern, components); CGContextSetStrokePattern(context, pattern, components); //绘制 CGContextFillRect(context, CGRectMake(0, 20, 155, 155)); CGContextStrokeRectWithWidth(context, CGRectMake(165,20, 155, 155), 5); }