zoukankan      html  css  js  c++  java
  • 关情纸尾-----Quartz2D-绘制圆形下载进度条,饼图

    绘制下载进度条

    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);
    把上下文渲染到View
    CGContextFillPath(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.

  • 相关阅读:
    6.00 Introduction to Computer Science and Programming lec5: Objects in Python
    6.00 Introduction to Computer Science and Programming lec3 & lec4
    DB2中查询表信息
    修改 unity “显示桌面”快捷键的方法 (Ubuntu 12.10)
    Ubuntu 12.10中阻止启动chrome时“unlock default keyring ...”弹出窗口的方法
    6.00 Introduction to Computer Science and Programming lec1
    Thinkpad T61显卡门的解决(更换集成显卡的主板)
    Ubuntu 12.10中安装Sun的JDK
    【设计模式】抽象工厂
    【设计模式】概述
  • 原文地址:https://www.cnblogs.com/Lorraine1/p/4794742.html
Copyright © 2011-2022 走看看