首页 > 学院 > 开发设计 > 正文

关情纸尾-----Quartz2D-绘制圆形下载进度条,饼图

2019-11-14 18:21:42
字体:
来源:转载
供稿:网友

绘制下载进度条

1.搭建界面.

2.拖动滑竿的时候让他里面的能够跟着我的拖动,数字在改变.
  数字改变时有一个注意点, 就是要显示%,它是一个特殊的符号,要用两个%%代表一个%

3.拖动滑竿的时候就是在上面画弧.
  从最上面,按顺时针画,所以,它的起始角度是-90度.结束角度也是-90度
  也是从起始角度开始画,
  起始角度-90度, 看你下载进度是多少
  假如说你下载进度是100,就是1 * 360度
  也就是说这个进度占你360度多少分之一

  CGContextRef ctx = UIGraphicsGetCurrentContext();  CGPoint center = CGPointMake(50, 50);  CGFloat radius = rect.size.width * 0.5;  CGFloat startA = -M_PI_2;  CGFloat endA = -M_PI_2 + M_PI * 2 * PRogress;  UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center                               radius:radius                             startAngle:startA                              endAngle:endA                              clockwise:YES];

  要获得Progress的值,这个进度值没有, 所以要传进来才能画.弄一个成员变量
  要在值改变的时候就要传进来.
  要拿到ProgressView才能够传进来,所以要拖线,拿到ProgressView
  所有都做好的, 发现没有画圆孤?
  为什么?
  问题:drawRect方法总共调用多少次?
  总共就调用一次, 第一次Progress为0,以后都不会执行了
  解决:每次传的时候,就要画一次,
  重写Progress方法
  

-(void)setProgress:(CGFloat)progress{    _progress = progress;      //手动调用drawRect方法, 让它重新绘制    [self setNeedsDisplay];}

  

 运行发现还是不画,为什么?

    原因:drawRect方法是不能手动调用,因为在drawRect方法中才能获取跟View相关联的上下文
    系统在调用DrawRect方法时,会自动帮你创建一个跟View相关联的上下文,并且传递给它.
    自己调用的,没有给drawRect方法传递上下文.所以在draw方法中拿不到上下文.

    解决办法:想要重绘,调用[self setNeedsDisplay];
    告诉系统重新绘制View,系统就会自动帮你调用drawRect方法,系统在调用
    drawRect方法,它会帮你创建上下文

 

绘制饼图

第一步, 获取上下文
第二步,拼接路径 ,绘制第一个扇形
获取上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();CGPoint center = CGPointMake(125, 125);CGFloat radius = 100;CGFloat startA = 0;CGFloat endA = 0;CGFloat angle = 25 / 100.0 * M_PI * 2;endA = startA + angle;

 

拼接路径

UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center                                radius:radius                              startAngle:startA                                endAngle:endA                               clockwise:YES];添加一根线到圆心[path addLineToPoint:center];把路径添加到上下文CGContextAddPath(ctx, path.CGPath);把上下文渲染到ViewCGContextFillPath(ctx);

 

注意点: CGFloat angle = 25 / 100.0 * M_PI * 2; 
100.0一定要加一个.0

绘制第二个扇形
一样的, 把路径描述第二个扇形就好了
直接来个path =
让Path指针重新指向一个新的对象.也就是把指针重复利用了
之前的那个对象已经用完了,已经添加到了上下文当中了.

第二个扇形

startA = endA;angle = 25 / 100.0 * M_PI * 2;endA = startA + angle;path = [UIBezierPath bezierPathWithArcCenter:center                          radius:radius                      startAngle:startA                       endAngle:endA                       clockwise:YES];            

 

[path addLineToPoint:center];
把二个路径添加到上下文
CGContextAddPath(ctx, path.CGPath);
把上下文渲染到View
CGContextFillPath(ctx);


添加第二个扇形之后, 发现它们的颜色都一样,想要修改它的颜色
在下面再写一个
[[UIColor greenColor] set];
下面的一个颜色把之前的东西给覆盖了.
解决办法, 让它渲染两次

第三个扇形,把第二个拷贝一下就好了


总结:
有没有发现在画三个扇形用太多代码了,
里面有很多代码相似.
是不是可以把代码给抽一下
可以用便利数组的的方式
发现就两个地方变了, 一个数字变了, 一个颜色变了.


抽取代码:
假设他给一组数据
NSArray datas = @[@25,@25,@50];
把数组便利出来

NSArray *datas = @[@25,@25,@50];CGPoint center = CGPointMake(125, 125);CGFloat radius = 100;CGFloat startA = 0;CGFloat angle = 0;CGFloat endA = 0;for (NSNumber *number in datas) {  startA = endA;  angle = number.intValue / 100.0 * M_PI * 2;  endA = startA + angle;  描述路径  UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center                                  radius:radius                               startAngle:startA                                endAngle:endA                                clockwise:YES];[path addLineToPoint:center];[[self randomColor] set];[path fill];}- (UIColor *)randomColor{  CGFloat r = arc4random_uniform(256)/ 255.0;  CGFloat g = arc4random_uniform(256)/ 255.0;  CGFloat b = arc4random_uniform(256)/ 255.0;  return [UIColor colorWithRed:r green:g blue:b alpha:1];}

随机颜色:alpha通道它的取值范围是0-255;
OC里面的取值范围只能是0到1,把它 / 255.0就让它到这个范围了,
arc4random_uniform(256)随机产生 0 - 255的数.
颜色通道它的取值范围是0 到 255.
所以说要把0 到 255转换成0 到 1
直接是 0 ~ 255 / 255.0就可以了.
刚好是255就是255 / 255.0 就是1,
刚才是0 就是 0 / 255.0 就是0.


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表