如何用两种不同的方法动态绘制饼状图

按照惯例先来交代故事背景,有人在问饼状图怎么动态来画?然后博主就在想,刚好最近一直在看动画的东西,虽然没直接画饼状图,但是通过属性调整,饼状图绘制起来也是妥妥的啊。于是综合前一阵子所学,用了以下两种方法来实现饼状图的绘制。首先,来看下效果图:
如何用两种不同的方法动态绘制饼状图_第1张图片

如有卡顿,请自行忽略,真机上是不会出现的。

第一种方法:使用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一样。

第一种方法下载
第二种方法下载

你可能感兴趣的:(Core,Animation)