某天,你正在上班ing……这个时候老大过来了,“小王啊,这个按钮太丑了,客户要求变成五角星形状的,UI没空给你切图,你给我完成这个需求啊”,说完便头也不回的走了,留下你一个人在冷风中摇曳,心里一万只草泥马在狂奔……
1.pngOK OK ,自己选的IOS开发,哭着也要完成…… 这里你可能就需要使用绘图这一块的知识了。如果你恰好这块还是比较空白的,那么就是。。。
2.gif. . .
没关系,先让我们重drawRect,这个方法开始吧。 首先了解一下这个东西干嘛的,怎么用,啥时候用。
1 干嘛的:如果你要对View进行绘制,那么你就要到这里处理2 怎么用:那当然是在这里涂鸦3 啥时候用:代码说明一切 -[DrawLineViewcontroller loadView] -[DrawLineViewcontroller viewDidLoad] -[DrawLineViewcontroller viewWillAppear:] -[DrawLineView drawRect:] -[DrawLineViewcontroller viewDidAppear:] 从上述代码我们看到他是在视图将要显示之后和显示之前调用的。. . . 通常我们需要进行一下的步骤进行绘制。
1 获取当前的上下文(这里只能获取一次,并且只能在drawRect方法中获取)2 描述路径、形状(就是处理想要显示的样子)3 把描述好的路径、形状添加早上下文中4 显示上下文内容. . .
额外属性:CGContextSetLineWidth(contextRef, 5); //设置线宽
. . .
方法一:
- (void)drawRect:(CGRect)rect { // Drawing code //1.获取上下文 CGContextRef contextRef = UIGraphicsGetCurrentContext(); //2.描述路径 UIBezierPath * path = [UIBezierPath bezierPath]; //起点 [path moveToPoint:CGPointMake(10, 10)]; //第二个点 [path addLineToPoint:CGPointMake(100, 10)]; //第三个点 [path addLineToPoint:CGPointMake(100, 100)]; //第四个点 [path addLineToPoint:CGPointMake(10, 100)]; //闭合路径 也等于 [path addLineToPoint:CGPointMake(10, 10)]; [path closePath]; //设置颜色 [[UIColor greenColor]setStroke]; //3.添加路径 CGContextAddPath(contextRef, path.CGPath); //显示路径 CGContextStrokePath(contextRef); }效果图
方法一方法二:通过一个起点和宽高,可计算出来矩形的大小位置
- (void)drawRect:(CGRect)rect { // Drawing code //1.获取上下文 CGContextRef contextRef = UIGraphicsGetCurrentContext(); //2.描述路径 UIBezierPath * path = [UIBezierPath bezierPathWithRect:CGRectMake(10, 10, 100, 100)]; //设置颜色 [[UIColor greenColor]set]; //3.添加路径 CGContextAddPath(contextRef, path.CGPath); //显示路径 CGContextFillPath(contextRef); }效果图:
方法二//设置描边颜色 [[UIColor greenColor]setStroke]; //显示描边路径 CGContextStrokePath(contextRef); //设置填充颜色 [[UIColor greenColor]set]; //显示填充路径 CGContextFillPath(contextRef);
. . .
方法一:
- (void)drawRect:(CGRect)rect { // Drawing code //1、获取当前上下文 CGContextRef contextRef = UIGraphicsGetCurrentContext(); //2.描述路径 //ArcCenter:中心点 //radius:半径 //startAngle:起始角度 //endAngle:结束角度 //clockwise:是否逆时针 UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width*0.5, self.bounds.size.height*0.5) radius:self.bounds.size.width*0.4 startAngle:0 endAngle:M_PI*2 clockwise:NO]; //3.添加路径到上下文 CGContextAddPath(contextRef, path.CGPath); //4.设置颜色 [[UIColor brownColor]setFill]; //4.显示上下文 显示一个实心圆 // CGContextFillPath(contextRef); //显示一个空心圆,描边 CGContextStrokePath(contextRef); }效果图:
效果图方法二:通过话椭圆的方式去画圆,大家都知道圆就是椭圆的一个特殊存在。宽高一致的时候就是圆形。
- (void)drawRect:(CGRect)rect { // Drawing code //1、获取当前上下文 CGContextRef contextRef = UIGraphicsGetCurrentContext(); //2.描述路径 这是画椭圆的方法,大家都知道 UIBezierPath * path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 10, 100, 100)]; //3.添加路径到上下文 CGContextAddPath(contextRef, path.CGPath); //4.设置颜色 [[UIColor redColor]setFill]; //4.显示上下文 CGContextFillPath(contextRef); } 效果图. . .
复杂版:
- (void)drawRect:(CGRect)rect { // Drawing code //1.获取当前上下文 CGContextRef contextRef = UIGraphicsGetCurrentContext(); //2.创建文字 NSString * str = @"纸巾艺术"; //设置字体样式 NSMutableDictionary * dict = [NSMutableDictionary dictionary]; //NSFontAttributeName:字体大小 dict[NSFontAttributeName] = [UIFont systemFontOfSize:25]; //字体前景色 dict[NSForegroundColorAttributeName] = [UIColor blueColor]; //字体背景色 dict[NSBackgroundColorAttributeName] = [UIColor redColor]; //字体阴影 NSShadow * shadow = [[NSShadow alloc]init]; //阴影偏移量 shadow.shadowOffset = CGSizeMake(2, 2); //阴影颜色 shadow.shadowColor = [UIColor greenColor]; //高斯模糊 shadow.shadowBlurRadius = 5; dict[NSShadowAttributeName] = shadow; //字体间距 dict[NSKernAttributeName] = @10; //绘制到上下文 //从某一点开始绘制 默认 0 0点 // [str drawAtPoint:CGPointMake(100, 100) withAttributes:nil]; //绘制区域设置 [str drawInRect:rect withAttributes:dict]; //添加到上下文 CGContextStrokePath(contextRef); } 复杂版效果图. . .
. . . . .
实现一个下载进度条
第一步:先创建一个工程第二步:创建一个View的子类,因为要重写drawRect方法第三步:重写DrawRect第四步:加载一张图片,绘制到上下文中 - (void)drawRect:(CGRect)rect { CGFloat startA = - M_PI_2; CGFloat endA = - M_PI_2 + self.progress * M_PI * 2; NSLog(@"%f - %f - %f",self.progress,(3.14159265359*self.progress)/180,endA); UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width*0.5, self.bounds.size.height*0.5) radius:self.bounds.size.width*0.5-10 startAngle:startA endAngle:endA clockwise:YES]; [path stroke]; }这里我们可以看到我并没有获取当前的上下文,这里是因为[path stroke]; 已经帮我们完成了其余的操作。 其实内部实现还是一样的!! 基本版效果:
基本版效果高能版:上面的只是完成了功能,但是却不好看!!然后我们稍稍的美化一下
- (void)drawRect:(CGRect)rect { CGFloat startA = - M_PI_2; CGFloat endA = - M_PI_2 + self.progress * M_PI * 2; NSLog(@"%f - %f - %f",self.progress,(3.14159265359*self.progress)/180,endA); UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width*0.5, self.bounds.size.height*0.5) radius:self.bounds.size.width*0.5-10 startAngle:startA endAngle:endA clockwise:YES]; [[UIColor colorWithRed:self.progress green:(1-self.progress) blue:0 alpha:1]setStroke]; path.lineWidth = 5; [path stroke]; } 动画版. . . . .
先跑出问题!
线这种线怎么处理!我们先实现三条线
- (void)drawRect:(CGRect)rect { // Drawing code UIBezierPath * path = [UIBezierPath bezierPath]; //设置线宽 path.lineWidth = 5; //第一条线 [[UIColor purpleColor]setStroke]; [path moveToPoint:CGPointMake(10, 10)]; [path addLineToPoint:CGPointMake(10, 100)]; //第二条线 [[UIColor orangeColor]setStroke]; [path moveToPoint:CGPointMake(30, 10)]; [path addLineToPoint:CGPointMake(30, 100)]; //第三条线 [[UIColor greenColor]setStroke]; [path moveToPoint:CGPointMake(50, 10)]; [path addLineToPoint:CGPointMake(50, 100)]; //使用描边方式添加到上下文中 [path stroke]; }你可能想当然的就这么做了,可是你发现效果是这样子的!!!
哎呀我去,为什么其实是这样子的
先设置了紫色 设置了橙色 设置了绿色所以,最后显示的就是绿色!!!!
这里我们还要了解一个东西! 上下文的状态栈。
21.png方法一:
- (void)drawRect:(CGRect)rect { // Drawing code //1 获取上下文 //分别设置线段的颜色 CGContextRef purple = UIGraphicsGetCurrentContext(); [[UIColor purpleColor]setStroke]; CGContextSaveGState(purple); CGContextRef orange = UIGraphicsGetCurrentContext(); [[UIColor orangeColor]setStroke]; CGContextSaveGState(orange); CGContextRef green = UIGraphicsGetCurrentContext(); [[UIColor greenColor]setStroke]; CGContextSaveGState(green); UIBezierPath * path = [UIBezierPath bezierPath]; //设置线宽 path.lineWidth = 5; //把紫色的上下文从栈中取出来 CGContextRestoreGState(purple); //第一条线 [[UIColor purpleColor]setStroke]; [path moveToPoint:CGPointMake(10, 10)]; [path addLineToPoint:CGPointMake(10, 100)]; [path stroke]; //把紫色的上下文从栈中取出来 CGContextRestoreGState(orange); path = [UIBezierPath bezierPath]; //设置线宽 path.lineWidth = 9; //第二条线 [[UIColor orangeColor]setStroke]; [path moveToPoint:CGPointMake(30, 10)]; [path addLineToPoint:CGPointMake(30, 100)]; [path stroke]; //把紫色的上下文从栈中取出来 CGContextRestoreGState(green); path = [UIBezierPath bezierPath]; //设置线宽 path.lineWidth = 3; //第三条线 [[UIColor greenColor]setStroke]; [path moveToPoint:CGPointMake(50, 10)]; [path addLineToPoint:CGPointMake(50, 100)]; [path stroke]; }方法二:
- (void)drawRect:(CGRect)rect { // Drawing code [[self bezierPathWithPoint:CGPointMake(10, 10) endPoint:CGPointMake(10, 180) lineColor:[UIColor purpleColor] lineWidth:6] stroke]; [[self bezierPathWithPoint:CGPointMake(50, 10) endPoint:CGPointMake(50, 180) lineColor:[UIColor greenColor] lineWidth:6] stroke]; [[self bezierPathWithPoint:CGPointMake(90, 10) endPoint:CGPointMake(90, 180) lineColor:[UIColor orangeColor] lineWidth:6] stroke]; } - (UIBezierPath *)bezierPathWithPoint:(CGPoint)startPoint endPoint:(CGPoint) endPoint lineColor:(UIColor*)lineColor lineWidth:(CGFloat)lineWidth{ UIBezierPath * path = [UIBezierPath bezierPath]; [lineColor setStroke]; path.lineWidth = lineWidth; [path moveToPoint:startPoint]; [path addLineToPoint:endPoint]; return path; } 了解了原理之后就这样子写快点啦