按照惯例先来交代故事背景,有人在问饼状图怎么动态来画?然后博主就在想,刚好最近一直在看动画的东西,虽然没直接画饼状图,但是通过属性调整,饼状图绘制起来也是妥妥的啊。于是综合前一阵子所学,用了以下两种方法来实现饼状图的绘制。首先,来看下效果图:
如有卡顿,请自行忽略,真机上是不会出现的。
第一种方法:使用CAShapeLayer,贝塞尔曲线和CABasicAnimation来画
原理:1.使用贝塞尔曲线决定绘制圆的路径和角度;
2.用CAShapeLayer来重合贝塞尔曲线的路径;
3.用基础动画来实现绘制的动态性。
1.使用贝塞尔曲线决定绘制圆的路径和角度
//用贝塞尔曲线来画扇形,实际上画的是圆,因为半径为边线中间到原点的距离,所以设置半径为线宽的一半,这样线宽就覆盖了中间填充部分的颜色,形成扇形。 UIBezierPath *bezierPath=[UIBezierPath bezierPathWithArcCenter:CGPointMake((self.view.frame.size.width)/2, (self.view.frame.size.height)/2) radius:60 startAngle:0 endAngle:M_PI/3*4 clockwise:YES];
2.用CAShapeLayer来重合贝塞尔曲线的路径
CAShapeLayer *shanxingLayer = [CAShapeLayer layer]; //这里设置填充线的宽度 shanxingLayer.lineWidth = 120; //设置拐角样式 shanxingLayer.lineCap = kCALineCapButt; //绘制的线的颜色 shanxingLayer.strokeColor = [[UIColor redColor] CGColor]; //填充色设置为nil是为了防止填充色混淆,因为这个本身实际上是画圆,第一步有解释 shanxingLayer.fillColor = nil; //路径 shanxingLayer.path = bezierPath.CGPath; [self.view.layer addSublayer:shanxingLayer];
3.用基础动画来实现绘制的动态性
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; //设置绘制动画持续的时间 animation.duration = 1; //速度控制函数 animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; //起始值 animation.fromValue = [NSNumber numberWithFloat:0.0f]; //结束值 animation.toValue = [NSNumber numberWithFloat:1.0f]; //是否翻转绘制 animation.autoreverses = NO; //当前对象在非active时间段的行为 animation.fillMode = kCAFillModeForwards; //重复次数 animation.repeatCount = 1; [shanxingLayer addAnimation:animation forKey:@"strokeEnd"]; //表示绘制到百分比多少就停止,这个我们用1表示完全绘制 shanxingLayer.strokeEnd=1.0f;
到这里就可以完成饼状图(扇形)的动态绘制了。代码中有详细的注解,博主就不多说明了。
第二种方法:利用CAShapeLayer的strokeStart和strokeSEnd两个属性和定时器
原理:1.CAShapeLayer的strokeStart和strokeEnd两个属性,前面博客在画圆时有用到这俩属性,strokeStart是起始位置,为三点钟方向,strokeEnd为结束绘制点,为一绘制的百分比,把贝塞尔曲线的路径给它;
2.利用定时器动态的改变绘制的百分比。
1.CAShapeLayer的strokeStart和strokeEnd两个属性,前面博客在画圆时有用到这俩属性,strokeStart是起始位置,为三点钟方向,strokeEnd为结束绘制点,为一绘制的百分比,把贝塞尔曲线的路径给它
- (void)draw { layer = [CAShapeLayer layer]; //这里设置填充线的宽度,这个参数很重要 layer.lineWidth = 120; //拐角设置 layer.lineCap = kCALineCapButt; //绘制的线的颜色 layer.strokeColor = [[UIColor redColor] CGColor]; layer.fillColor = nil; layer.strokeStart=0; layer.strokeEnd=end/10; [self.view.layer addSublayer:layer]; //用贝塞尔曲线来画扇形,实际上画的是圆,因为半径为边线中间到原点的距离,所以设置半径为线宽的一半,这样线宽就覆盖了中间填充部分的颜色,形成扇形 UIBezierPath *bezierPath=[UIBezierPath bezierPathWithArcCenter:CGPointMake((self.view.frame.size.width)/2, (self.view.frame.size.height)/2) radius:60 startAngle:0 endAngle:M_PI/2*3 clockwise:YES]; layer.path = bezierPath.CGPath; }
2.利用定时器动态的改变绘制的百分比
- (void)updateLayer { //起始点为0,结束点不断增加,圆的弧线越来越长,到结束点闭合就变成了圆,我们这里按贝斯阿尔曲线路径到结束点为一扇形 if ( end < 10) { end ++; } else { [timer invalidate]; } NSLog(@"----"); layer.strokeEnd = end/10.0; }
如果你对动画稍有了解,如果你看过博主的其它博文,那这里的代码对你来说小菜一碟,完全没有难度,如果是新手,因为代码从未接触过,你会觉得难,其实就好比你初次接触Object-C一样。