LoginSignup
23
25

More than 5 years have passed since last update.

【iOS】【Objective-C】アニメーション付き円グラフ

Posted at

円グラフをアニメーション付きに。下のような感じで。



gifちらつきますが..

真ん中くりぬきと、そうじゃないバージョンで。

まずはObjective-C版を。
valueとcolorを渡すイメージで実装。

PieGraphView.m

#import "PieGraphView.h"

@implementation PieGraphView
{
    NSArray *_params;
    float _end_angle;
}

-(PieGraphView*)initWithFrame:(CGRect)frame params:(NSArray*)params
{
    self = [super initWithFrame:frame];
    if (self) {
        _params = params;
        self.backgroundColor = [UIColor clearColor];
        _end_angle = -M_PI / 2;
    }
    return self;
}


-(void)update:(id)link{
    _end_angle +=  (M_PI*2 )/ 100;
    if(_end_angle > M_PI*2) {
        //終了
        [link invalidate];
    } else {
        [self setNeedsDisplay];
    }
}

//開始メソッド
-(void)startAnimating
{
    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)];
    [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGFloat x = rect.origin.x;
    x += rect.size.width/2;
    CGFloat y = rect.origin.y;
    y += rect.size.height/2;
    float max = 0;
    for(NSDictionary *dic in _params){
        float value = [dic[@"value"] floatValue];
        max += value;
    }


    float start_angle = -M_PI / 2;
    float end_angle   = 0;
    float radius = x-10;
    for(NSDictionary *dic in _params){
        float   value = [dic[@"value"] floatValue];
        end_angle = start_angle + M_PI*2 * (value/max);
        if(end_angle > _end_angle) {
            end_angle = _end_angle;
        }
        UIColor *color = dic[@"color"];
        CGContextMoveToPoint(context, x, y);
        CGContextAddArc(context, x, y, radius,  start_angle, end_angle, 0);
//これを有効にすると、中をくりぬき
//        CGContextAddArc(context, x, y, radius/2,  end_angle, start_angle, true);
        CGContextSetFillColor(context, CGColorGetComponents([color CGColor]));
        CGContextClosePath(context);
        CGContextFillPath(context);
        start_angle = end_angle;
    }

}

@end

PieGraphView.h

#import <UIKit/UIKit.h>

@interface PieGraphView : UIView
-(PieGraphView*)initWithFrame:(CGRect)frame params:(NSArray*)params;
-(void)startAnimating;
@end

利用イメージは以下のようなものを検討しています。

ViewController.m


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSMutableArray *params = [[NSMutableArray alloc] init];
    [params addObject:@{@"value":@7,@"color":[UIColor redColor]}];
    [params addObject:@{@"value":@5,@"color":[UIColor blueColor]}];
    [params addObject:@{@"value":@8,@"color":[UIColor greenColor]}];
    [params addObject:@{@"value":@10,@"color":[UIColor yellowColor]}];
    graphView = [[PieGraphView alloc] initWithFrame:CGRectMake(0, 30, 320, 320) params:params];
    [self.view addSubview:graphView];
}

- (IBAction)start:(id)sender {
    [graphView startAnimating];
}


23
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
25