赞
踩
某天,你正在上班ing……这个时候老大过来了,“小王啊,这个按钮太丑了,客户要求变成五角星形状的,UI没空给你切图,你给我完成这个需求啊”,说完便头也不回的走了,留下你一个人在冷风中摇曳,心里一万只草泥马在狂奔……
OK OK ,自己选的IOS开发,哭着也要完成…… 这里你可能就需要使用绘图这一块的知识了。如果你恰好这块还是比较空白的,那么就是。。。
.
.
.
没关系,先让我们重drawRect,这个方法开始吧。
首先了解一下这个东西干嘛的,怎么用,啥时候用。
- 1 干嘛的:如果你要对View进行绘制,那么你就要到这里处理
- 2 怎么用:那当然是在这里涂鸦
- 3 啥时候用:代码说明一切
从上述代码我们看到他是在视图将要显示之后和显示之前调用的。
-[DrawLineViewcontroller loadView] -[DrawLineViewcontroller viewDidLoad] -[DrawLineViewcontroller viewWillAppear:] -[DrawLineView drawRect:] -[DrawLineViewcontroller viewDidAppear:]
.
.
.
通常我们需要进行一下的步骤进行绘制。
- 1 获取当前的上下文(这里只能获取一次,并且只能在drawRect方法中获取)
- 2 描述路径、形状(就是处理想要显示的样子)
- 3 把描述好的路径、形状添加早上下文中
- 4 显示上下文内容
.
.
.
1 画线
- 第一步:先创建一个工程
- 第二步:创建一个View的子类,因为要重写drawRect方法
- 第三步:重写DrawRect
- 第四步:先了解一下线段是如何绘制的,额……两个点确定一条直线,这些东西大家都懂,所以我们需要一个起点和一个终点来确定一条直线。
- - (void)drawRect:(CGRect)rect {
- // Drawing code
- NSLog(@"%s",__func__);
- //1.获取上下文
- CGContextRef contextRef = UIGraphicsGetCurrentContext();
- //2.描述路径
- UIBezierPath * path = [UIBezierPath bezierPath];
- //起点
- [path moveToPoint:CGPointMake(10, 10)];
- //终点
- [path addLineToPoint:CGPointMake(100, 100)];
- //设置颜色
- [[UIColor whiteColor]setStroke];
- //3.添加路径
- CGContextAddPath(contextRef, path.CGPath);
- //显示路径
- CGContextStrokePath(contextRef);
-
- }
额外属性:CGContextSetLineWidth(contextRef, 5); //设置线宽
.
.
.
1 画矩形
- 第一步:先创建一个工程
- 第二步:创建一个View的子类,因为要重写drawRect方法
- 第三步:重写DrawRect
- 第四步:先了解一下矩形是如何绘制的,矩形是由四个边组成,所以我们画四条线段便可以画一个矩形。
方法一:
- - (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);
.
.
.
3 画圆
- 第一步:先创建一个工程
- 第二步:创建一个View的子类,因为要重写drawRect方法
- 第三步:重写DrawRect
- 第四步:先了解一下圆形是如何绘制的,要确定圆心、半径,以及旋转的角度。
方法一:
- - (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);
-
- }
.
.
.
4 画文字
- 第一步:先创建一个工程
- 第二步:创建一个View的子类,因为要重写drawRect方法
- 第三步:重写DrawRect
- 第四步:写一段文字,把文字绘制到上下文中
- - (void)drawRect:(CGRect)rect {
- // Drawing code
-
- //1.获取当前上下文
- CGContextRef contextRef = UIGraphicsGetCurrentContext();
- //2.创建文字
- NSString * str = @"纸巾艺术";
- //会知道上下文
- [str drawInRect:rect withAttributes:nil];
- CGContextStrokePath(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);
- }
.
.
.
5 画图片
- 第一步:先创建一个工程
- 第二步:创建一个View的子类,因为要重写drawRect方法
- 第三步:重写DrawRect
- 第四步:加载一张图片,绘制到上下文中
- - (void)drawRect:(CGRect)rect {
- // Drawing code
-
- //1.获取当前的上下文
- CGContextRef contextRef = UIGraphicsGetCurrentContext();
- //2.加载图片
- //这里顺便咯嗦一句:使用imageNamed加载图片是会有缓存的
- //我们这里只需要加载一次就够了,不需要多次加载,所以不应该保存这个缓存
- // UIImage * image = [UIImage imageNamed:@"222"]; //所以可以换一种方式去加载
- UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"222.png" ofType:nil]];
-
-
- // //绘制的大小位置
- // [image drawInRect:rect];
-
-
- // //从某个点开始绘制
- // [image drawAtPoint:CGPointMake(0, 0)];
-
-
- //绘制一个多大的图片,并且设置他的混合模式以及透明度
- //Rect:大小位置
- //blendModel:混合模式
- //alpha:透明度
- [image drawInRect:rect blendMode:kCGBlendModeNormal alpha:1];
-
-
- //从某一点开始绘制图片,并设置混合模式以及透明度
- //point:开始位置
- //blendModel:混合模式
- //alpha:透明度
- // [image drawAtPoint:CGPointMake(0, 0) blendMode:kCGBlendModeNormal alpha:1];
-
- //添加到上下文
- CGContextFillPath(contextRef);
- }
.
.
.
.
.
6 综合实例:
1 重绘
实现一个下载进度条
- 第一步:先创建一个工程
- 第二步:创建一个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];
-
- }
.
.
.
.
.
2 不同颜色的线
先跑出问题!
这种线怎么处理!我们先实现三条线
- - (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];
- }
你可能想当然的就这么做了,可是你发现效果是这样子的!!!
其实是这样子的
所以,最后显示的就是绿色!!!!
这里我们还要了解一个东西!
上下文的状态栈。
方法一:
- - (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;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。