Quartz2D-下载进条AND画饼图

Posted by Chen on September 21, 2016

# #03-下载进条. 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 drawRect:self.bounds]; } 运行发现还是不画,为什么? 原因: drawRect方法是不能手动调用,因为在drawRect方法中才能获取跟View相关联的上下文 系统在调用DrawRect方法时,会自动帮你创建一个跟View相关联的上下文,并且传递给它. 自己调用的,没有给drawRect方法传递上下文.所以在draw方法中拿不到上下文. 解决办法: 想要重绘,调用[self setNeedsDisplay]; 告诉系统重新绘制View,系统就会自动帮你调用drawRect方法,系统在调用 drawRect方法,它会帮你创建上下文

# #04-画饼图

业务逻辑 在屏幕上面显示一个饼图 实现思路 分别画三个扇形,把三个扇形添加到一起, 把上一个扇形的终点当做是下一个扇形的起点. 具体代码 第一步, 获取上下文 第二步,拼接路径 ,绘制第一个扇形 获取上下文 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.