画饼状图三

来源:互联网 发布:hibernate注解写sql 编辑:程序博客网 时间:2024/05/16 17:49

直接上代码了,这里加上了动画,代码中记录了我是怎么想的,怎么做的,后期会加上点击功能。

#import "GY_PieChart.h"@interface GY_PieChart ()@property (nonatomic, assign) CGFloat startAngle;@property (nonatomic, assign) CGFloat endAngle;@property (nonatomic, strong) NSMutableArray *valuesAry;@property (nonatomic, strong) NSMutableArray *colorsAry;@property (nonatomic, strong) NSMutableArray * arcLayers;@property (nonatomic, assign) NSInteger currentArcIndex;  //用于标记当前播放到那个扇形了@end@implementation GY_PieChart- (instancetype)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        [self setBackgroundColor:[UIColor cyanColor]];        _currentArcIndex = 0;        _totalPlayTime = 1;        _valuesAry = [[NSMutableArray alloc] initWithObjects:@"20",@"10",@"30",@"40", nil];        _colorsAry = [[NSMutableArray alloc] initWithObjects:[UIColor blackColor],[UIColor yellowColor],[UIColor brownColor],[UIColor whiteColor], nil];        _arcLayers = [[NSMutableArray alloc] init];    }    return self;}// Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)drawRect:(CGRect)rect {    // Drawing code}#pragma mark - 动画/** *  填充动画过程 * *  @return CABasicAnimation */- (CABasicAnimation *)animation {    CABasicAnimation * fillAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];    fillAnimation.duration = [self cacaulatecurrentArcDuration];    fillAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];    fillAnimation.fillMode = kCAFillModeForwards;    fillAnimation.removedOnCompletion = YES;    fillAnimation.fromValue = @(0.f);    fillAnimation.toValue = @(1.f);    fillAnimation.delegate = self;    return fillAnimation;}/** *  这是要绘制的扇形的路径,路径交给shapeLayer:去绘制扇形 * *  @return UIBezierPath */- (UIBezierPath *)fill {    //需要多少度的圆弧    CGPoint arcCenter = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);    UIBezierPath *_bezierpath = [UIBezierPath bezierPathWithArcCenter:arcCenter                                                                radius:self.frame.size.width/4                                                            startAngle:_startAngle                                                              endAngle:_endAngle                                                             clockwise:YES];    _startAngle = _endAngle;    return _bezierpath;}//制作扇形,添加动画- (CAShapeLayer *)shapeLayer:(UIColor *)color {    CAShapeLayer * layer = [CAShapeLayer layer];    layer.fillColor = nil;    layer.strokeColor = color.CGColor;    layer.lineWidth = self.frame.size.width/2;    layer.path = [self fill].CGPath;        CABasicAnimation * animation = [self animation];    [layer addAnimation:animation forKey:nil];        return layer;}//移除绘制的扇形- (void)removeAllSubLayers {    for (CAShapeLayer * layer in _arcLayers) {        [layer removeFromSuperlayer];    }    [_arcLayers removeAllObjects];}/** *  重绘,设置初始值 */- (void)strokePath {    [self removeAllSubLayers];    _currentArcIndex = 0;    _startAngle = -M_PI_2;    [self strokeSinglePath];}/** *  重绘单个扇形,这里是准备绘制扇形的参数 */- (void)strokeSinglePath {    _endAngle = _startAngle + [self cacaulatecurrentArcPercent]*M_PI*2;    [self startStroke];}/** *  开始干活,绘制扇形添加到页面上,只管干活,判断什么的不用我管,给我什么我绘制什么 */- (void)startStroke {    NSLog(@"do:%ld",_currentArcIndex);    CAShapeLayer *layer = [self shapeLayer:[self.colorsAry objectAtIndex:_currentArcIndex]];    [self.layer addSublayer:layer];    [self.arcLayers addObject:layer];}/** *  是否是最后一个扇形,用于在绘制最后一个扇形时,设置endAngle */- (BOOL)isLast {    if (_currentArcIndex==[_valuesAry count]-1) {        return YES;    }    return NO;}/** *  计算每个扇形的数值占总数的比例 */- (CGFloat)cacaulatecurrentArcPercent {    CGFloat valueF = [[_valuesAry objectAtIndex:_currentArcIndex] floatValue];    CGFloat rate = valueF/100;    return rate;}/** *  计算每个扇形绘制动画需要的时间,这里以画一圈圆需要2秒为默认值,每个扇形根据它自己数值的大小去分这2秒 */- (CGFloat)cacaulatecurrentArcDuration {    NSLog(@"animition time: %f",[self cacaulatecurrentArcPercent]*_totalPlayTime);    return [self cacaulatecurrentArcPercent]*_totalPlayTime;}/** *  这是我思想的核心,我的想法是当一个扇形的动画展示完毕,再去绘制下一个,知道结束 */- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{    if (flag) {        _currentArcIndex++;        if (_currentArcIndex < [_valuesAry count]) {            if ([self isLast]) {                _endAngle = M_PI*0.75*2;            }            [self strokeSinglePath];        }    }}@end


1 0
原创粉丝点击