在iOS中常用的绘图框架就是Quartz 2D,Quartz 2D是Core Graphics框架的一部分,是一个强大的二维图像绘制引擎。Quartz 2D在UIKit中也有很好的封装和集成,我们日常开发时所用到的UIKit中的组件都是由Core Graphics进行绘制的。不仅如此,当我们引入UIKit框架时系统会自动引入Core Graphics框架,并且为了方便开发者使用在UIKit内部还对一些常用的绘图API进行了封装。
-(void)drawLine2{ //1.获得图形上下文 CGContextRef context=UIGraphicsGetCurrentContext(); //2.绘制路径(相当于前面创建路径并添加路径到图形上下文两步操作) CGContextMoveToPoint(context, 20, 50); CGContextAddLineToPoint(context, 20, 100); CGContextAddLineToPoint(context, 300, 100); //封闭路径:a.创建一条起点和终点的线,不推荐 //CGPathAddLineToPoint(path, nil, 20, 50); //封闭路径:b.直接调用路径封闭方法 CGContextClosePath(context); //3.设置图形上下文属性 [[UIColor redColor]setStroke];//设置红色边框 [[UIColor greenColor]setFill];//设置绿色填充 //[[UIColor blueColor]set];//同时设置填充和边框色 //4.绘制路径 CGContextDrawPath(context, kCGPathFillStroke); }
绘制矩形
在下面的方法中还可以看到UIKit对绘图方法的封装,使用起来更加简单。
#pragma mark 绘制矩形 -(void)drawRectWithContext:(CGContextRef)context{ //添加矩形对象 CGRect rect=CGRectMake(20, 50, 280.0, 50.0); CGContextAddRect(context,rect); //设置属性 [[UIColor blueColor]set]; //绘制 CGContextDrawPath(context, kCGPathFillStroke); } #pragma mark 绘制矩形(利用UIKit的封装方法) -(void)drawRectByUIKitWithContext:(CGContextRef)context{ CGRect rect= CGRectMake(20, 150, 280.0, 50.0); CGRect rect2=CGRectMake(20, 250, 280.0, 50.0); //设置属性 [[UIColor yellowColor]set]; //绘制矩形,相当于创建对象、添加对象到上下文、绘制三个步骤 UIRectFill(rect);//绘制矩形(只有填充) [[UIColor redColor]setStroke]; UIRectFrame(rect2);//绘制矩形(只有边框) } @end
绘制椭圆
#pragma mark 绘制椭圆 -(void)drawEllipse:(CGContextRef)context{ //添加对象,绘制椭圆(圆形)的过程也是先创建一个矩形 CGRect rect=CGRectMake(50, 50, 220.0, 200.0); CGContextAddEllipseInRect(context, rect); //设置属性 [[UIColor purpleColor]set]; //绘制 CGContextDrawPath(context, kCGPathFillStroke); } @end
绘制弧形
-(void)drawArc:(CGContextRef)context{ /*添加弧形对象 x:中心点x坐标 y:中心点y坐标 radius:半径 startAngle:起始弧度 endAngle:终止弧度 closewise:是否逆时针绘制,0则顺时针绘制 */ CGContextAddArc(context, 160, 160, 100.0, 0.0, M_PI_2, 1); //设置属性 [[UIColor yellowColor]set]; //绘制 CGContextDrawPath(context, kCGPathFillStroke); }
#pragma mark 绘制贝塞尔曲线 -(void)drawCurve:(CGContextRef)context{ //绘制曲线 CGContextMoveToPoint(context, 20, 100);//移动到起始位置 /*绘制二次贝塞尔曲线 c:图形上下文 cpx:控制点x坐标 cpy:控制点y坐标 x:结束点x坐标 y:结束点y坐标 */ CGContextAddQuadCurveToPoint(context, 160, 0, 300, 100); CGContextMoveToPoint(context, 20, 500); /*绘制三次贝塞尔曲线 c:图形上下文 cp1x:第一个控制点x坐标 cp1y:第一个控制点y坐标 cp2x:第二个控制点x坐标 cp2y:第二个控制点y坐标 x:结束点x坐标 y:结束点y坐标 */ CGContextAddCurveToPoint(context, 80, 300, 240, 500, 300, 300); //设置图形上下文属性 [[UIColor yellowColor]setFill]; [[UIColor redColor]setStroke]; //绘制路径 CGContextDrawPath(context, kCGPathFillStroke); }
文字绘制
除了绘制图形还可以绘制文本内容。
-(void)drawText:(CGContextRef)context{ //绘制到指定的区域内容 NSString *str=@"Star Walk is the most beautiful stargazing app you’ve ever seen on a mobile device. It will become your go-to interactive astro guide to the night sky, following your every movement in real-time and allowing you to explore over 200, 000 celestial bodies with extensive information about stars and constellations that you find."; CGRect rect= CGRectMake(20, 50, 280, 300); UIFont *font=[UIFont systemFontOfSize:18];//设置字体 UIColor *color=[UIColor redColor];//字体颜色 NSMutableParagraphStyle *style=[[NSMutableParagraphStyle alloc]init];//段落样式 NSTextAlignment align=NSTextAlignmentLeft;//对齐方式 style.alignment=align; [str drawInRect:rect withAttributes:@{NSFontAttributeName:font,NSForegroundColorAttributeName:color,NSParagraphStyleAttributeName:style}]; }
图像绘制
Quartz 2D还可以将图像绘制到图形上下文。
-(void)drawImage:(CGContextRef)context{ UIImage *image=[UIImage imageNamed:@"image2.jpg"]; //从某一点开始绘制 [image drawAtPoint:CGPointMake(10, 50)]; //绘制到指定的矩形中,注意如果大小不合适会会进行拉伸 // [image drawInRect:CGRectMake(10, 50, 300, 450)]; //平铺绘制 // [image drawAsPatternInRect:CGRectMake(0, 0, 320, 568)]; }
#import "KCView3.h" @implementation KCView3 -(void)drawRect:(CGRect)rect{ CGContextRef context=UIGraphicsGetCurrentContext(); // [self drawLinearGradient:context]; [self drawRadialGradient:context]; } #pragma mark 线性渐变 -(void)drawLinearGradient:(CGContextRef)context{ //使用rgb颜色空间 CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB(); /*指定渐变色 space:颜色空间 components:颜色数组,注意由于指定了RGB颜色空间,那么四个数组元素表示一个颜色(red、green、blue、alpha), 如果有三个颜色则这个数组有4*3个元素 locations:颜色所在位置(范围0~1),这个数组的个数不小于components中存放颜色的个数 count:渐变个数,等于locations的个数 */ CGFloat compoents[12]={ 248.0/255.0,86.0/255.0,86.0/255.0,1, 249.0/255.0,127.0/255.0,127.0/255.0,1, 1.0,1.0,1.0,1.0 }; CGFloat locations[3]={0,0.3,1.0}; CGGradientRef gradient= CGGradientCreateWithColorComponents(colorSpace, compoents, locations, 3); /*绘制线性渐变 context:图形上下文 gradient:渐变色 startPoint:起始位置 endPoint:终止位置 options:绘制方式,kCGGradientDrawsBeforeStartLocation 开始位置之前就进行绘制,到结束位置之后不再绘制, kCGGradientDrawsAfterEndLocation开始位置之前不进行绘制,到结束点之后继续填充 */ CGContextDrawLinearGradient(context, gradient, CGPointZero, CGPointMake(320, 300), kCGGradientDrawsAfterEndLocation); //释放颜色空间 CGColorSpaceRelease(colorSpace); } #pragma mark 径向渐变 -(void)drawRadialGradient:(CGContextRef)context{ //使用rgb颜色空间 CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB(); /*指定渐变色 space:颜色空间 components:颜色数组,注意由于指定了RGB颜色空间,那么四个数组元素表示一个颜色(red、green、blue、alpha), 如果有三个颜色则这个数组有4*3个元素 locations:颜色所在位置(范围0~1),这个数组的个数不小于components中存放颜色的个数 count:渐变个数,等于locations的个数 */ CGFloat compoents[12]={ 248.0/255.0,86.0/255.0,86.0/255.0,1, 249.0/255.0,127.0/255.0,127.0/255.0,1, 1.0,1.0,1.0,1.0 }; CGFloat locations[3]={0,0.3,1.0}; CGGradientRef gradient= CGGradientCreateWithColorComponents(colorSpace, compoents, locations, 3); /*绘制径向渐变 context:图形上下文 gradient:渐变色 startCenter:起始点位置 startRadius:起始半径(通常为0,否则在此半径范围内容无任何填充) endCenter:终点位置(通常和起始点相同,否则会有偏移) endRadius:终点半径(也就是渐变的扩散长度) options:绘制方式,kCGGradientDrawsBeforeStartLocation 开始位置之前就进行绘制,但是到结束位置之后不再绘制, kCGGradientDrawsAfterEndLocation开始位置之前不进行绘制,但到结束点之后继续填充 */ CGContextDrawRadialGradient(context, gradient, CGPointMake(160, 284),0, CGPointMake(165, 289), 150, kCGGradientDrawsAfterEndLocation); //释放颜色空间 CGColorSpaceRelease(colorSpace); } @end
-(void)drawRectWithLinearGradientFill:(CGContextRef)context{ CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB(); //裁切处一块矩形用于显示,注意必须先裁切再调用渐变 //CGContextClipToRect(context, CGRectMake(20, 50, 280, 300)); //裁切还可以使用UIKit中对应的方法 UIRectClip(CGRectMake(20, 50, 280, 300)); CGFloat compoents[12]={ 248.0/255.0,86.0/255.0,86.0/255.0,1, 249.0/255.0,127.0/255.0,127.0/255.0,1, 1.0,1.0,1.0,1.0 }; CGFloat locations[3]={0,0.3,1.0}; CGGradientRef gradient= CGGradientCreateWithColorComponents(colorSpace, compoents, locations, 3); CGContextDrawLinearGradient(context, gradient, CGPointMake(20, 50), CGPointMake(300, 300), kCGGradientDrawsAfterEndLocation); //释放颜色空间 CGColorSpaceRelease(colorSpace); }
叠加模式
使用Quartz 2D绘图时后面绘制的图像会覆盖前面的,默认情况下如果前面的被覆盖后将看不到后面的内容,但是有时候这个结果并不是我们想要的,因此在Quartz 2D中提供了填充模式供开发者配置调整。由于填充模式类别特别多,因此下面以一个例子来说明:
-(void)drawRectByUIKitWithContext2:(CGContextRef)context{ CGRect rect= CGRectMake(0, 130.0, 320.0, 50.0); CGRect rect1= CGRectMake(0, 390.0, 320.0, 50.0); CGRect rect2=CGRectMake(20, 50.0, 10.0, 250.0); CGRect rect3=CGRectMake(40.0, 50.0, 10.0, 250.0); CGRect rect4=CGRectMake(60.0, 50.0, 10.0, 250.0); CGRect rect5=CGRectMake(80.0, 50.0, 10.0, 250.0); CGRect rect6=CGRectMake(100.0, 50.0, 10.0, 250.0); CGRect rect7=CGRectMake(120.0, 50.0, 10.0, 250.0); CGRect rect8=CGRectMake(140.0, 50.0, 10.0, 250.0); CGRect rect9=CGRectMake(160.0, 50.0, 10.0, 250.0); CGRect rect10=CGRectMake(180.0, 50.0, 10.0, 250.0); CGRect rect11=CGRectMake(200.0, 50.0, 10.0, 250.0); CGRect rect12=CGRectMake(220.0, 50.0, 10.0, 250.0); CGRect rect13=CGRectMake(240.0, 50.0, 10.0, 250.0); CGRect rect14=CGRectMake(260.0, 50.0, 10.0, 250.0); CGRect rect15=CGRectMake(280.0, 50.0, 10.0, 250.0); CGRect rect16=CGRectMake(30.0, 310.0, 10.0, 250.0); CGRect rect17=CGRectMake(50.0, 310.0, 10.0, 250.0); CGRect rect18=CGRectMake(70.0, 310.0, 10.0, 250.0); CGRect rect19=CGRectMake(90.0, 310.0, 10.0, 250.0); CGRect rect20=CGRectMake(110.0, 310.0, 10.0, 250.0); CGRect rect21=CGRectMake(130.0, 310.0, 10.0, 250.0); CGRect rect22=CGRectMake(150.0, 310.0, 10.0, 250.0); CGRect rect23=CGRectMake(170.0, 310.0, 10.0, 250.0); CGRect rect24=CGRectMake(190.0, 310.0, 10.0, 250.0); CGRect rect25=CGRectMake(210.0, 310.0, 10.0, 250.0); CGRect rect26=CGRectMake(230.0, 310.0, 10.0, 250.0); CGRect rect27=CGRectMake(250.0, 310.0, 10.0, 250.0); CGRect rect28=CGRectMake(270.0, 310.0, 10.0, 250.0); CGRect rect29=CGRectMake(290.0, 310.0, 10.0, 250.0); [[UIColor yellowColor]set]; UIRectFill(rect); [[UIColor greenColor]setFill]; UIRectFill(rect1); [[UIColor redColor]setFill]; UIRectFillUsingBlendMode(rect2, kCGBlendModeClear); UIRectFillUsingBlendMode(rect3, kCGBlendModeColor); UIRectFillUsingBlendMode(rect4, kCGBlendModeColorBurn); UIRectFillUsingBlendMode(rect5, kCGBlendModeColorDodge); UIRectFillUsingBlendMode(rect6, kCGBlendModeCopy); UIRectFillUsingBlendMode(rect7, kCGBlendModeDarken); UIRectFillUsingBlendMode(rect8, kCGBlendModeDestinationAtop); UIRectFillUsingBlendMode(rect9, kCGBlendModeDestinationIn); UIRectFillUsingBlendMode(rect10, kCGBlendModeDestinationOut); UIRectFillUsingBlendMode(rect11, kCGBlendModeDestinationOver); UIRectFillUsingBlendMode(rect12, kCGBlendModeDifference); UIRectFillUsingBlendMode(rect13, kCGBlendModeExclusion); UIRectFillUsingBlendMode(rect14, kCGBlendModeHardLight); UIRectFillUsingBlendMode(rect15, kCGBlendModeHue); UIRectFillUsingBlendMode(rect16, kCGBlendModeLighten); UIRectFillUsingBlendMode(rect17, kCGBlendModeLuminosity); UIRectFillUsingBlendMode(rect18, kCGBlendModeMultiply); UIRectFillUsingBlendMode(rect19, kCGBlendModeNormal); UIRectFillUsingBlendMode(rect20, kCGBlendModeOverlay); UIRectFillUsingBlendMode(rect21, kCGBlendModePlusDarker); UIRectFillUsingBlendMode(rect22, kCGBlendModePlusLighter); UIRectFillUsingBlendMode(rect23, kCGBlendModeSaturation); UIRectFillUsingBlendMode(rect24, kCGBlendModeScreen); UIRectFillUsingBlendMode(rect25, kCGBlendModeSoftLight); UIRectFillUsingBlendMode(rect26, kCGBlendModeSourceAtop); UIRectFillUsingBlendMode(rect27, kCGBlendModeSourceIn); UIRectFillUsingBlendMode(rect28, kCGBlendModeSourceOut); UIRectFillUsingBlendMode(rect29, kCGBlendModeXOR); }