円グラフをアニメーション付きに。下のような感じで。
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];
}