今天项目增加新功能,某页面需要扇形统计图,宝宝拿来分享一下~
前面两个.h .m文件是某位大神已经写好的。后面是使用方法。
需要遵守DataSource和Delegate协议。
XYPieChart.h
#import <UIKit/UIKit.h> @class XYPieChart; @protocol XYPieChartDataSource <NSObject> @required - (NSUInteger)numberOfSlicesInPieChart:(XYPieChart *)pieChart; - (CGFloat)pieChart:(XYPieChart *)pieChart valueForSliceAtIndex:(NSUInteger)index; @optional - (UIColor *)pieChart:(XYPieChart *)pieChart colorForSliceAtIndex:(NSUInteger)index; - (NSString *)pieChart:(XYPieChart *)pieChart textForSliceAtIndex:(NSUInteger)index; @end @protocol XYPieChartDelegate <NSObject> @optional - (void)pieChart:(XYPieChart *)pieChart willSelectSliceAtIndex:(NSUInteger)index; - (void)pieChart:(XYPieChart *)pieChart didSelectSliceAtIndex:(NSUInteger)index; - (void)pieChart:(XYPieChart *)pieChart willDeselectSliceAtIndex:(NSUInteger)index; - (void)pieChart:(XYPieChart *)pieChart didDeselectSliceAtIndex:(NSUInteger)index; @end @interface XYPieChart : UIView @property(nonatomic, weak) id<XYPieChartDataSource> dataSource; @property(nonatomic, weak) id<XYPieChartDelegate> delegate; @property(nonatomic, assign) CGFloat startPieAngle; @property(nonatomic, assign) CGFloat animationSpeed; @property(nonatomic, assign) CGPoint pieCenter; @property(nonatomic, assign) CGFloat pieRadius; @property(nonatomic, assign) BOOL showLabel; @property(nonatomic, strong) UIFont *labelFont; @property(nonatomic, strong) UIColor *labelColor; @property(nonatomic, strong) UIColor *labelShadowColor; @property(nonatomic, assign) CGFloat labelRadius; @property(nonatomic, assign) CGFloat selectedSliceStroke; @property(nonatomic, assign) CGFloat selectedSliceOffsetRadius; @property(nonatomic, assign) BOOL showPercentage; - (id)initWithFrame:(CGRect)frame Center:(CGPoint)center Radius:(CGFloat)radius; - (void)reloadData; - (void)setPieBackgroundColor:(UIColor *)color; - (void)setSliceSelectedAtIndex:(NSInteger)index; - (void)setSliceDeselectedAtIndex:(NSInteger)index; @end;
XYPieChart.m
#import "XYPieChart.h" #import <QuartzCore/QuartzCore.h> @interface SliceLayer : CAShapeLayer @property (nonatomic, assign) CGFloat value; @property (nonatomic, assign) CGFloat percentage; @property (nonatomic, assign) double startAngle; @property (nonatomic, assign) double endAngle; @property (nonatomic, assign) BOOL isSelected; @property (nonatomic, strong) NSString *text; - (void)createArcAnimationForKey:(NSString *)key fromValue:(NSNumber *)from toValue:(NSNumber *)to Delegate:(id)delegate; @end @implementation SliceLayer @synthesize text = _text; @synthesize value = _value; @synthesize percentage = _percentage; @synthesize startAngle = _startAngle; @synthesize endAngle = _endAngle; @synthesize isSelected = _isSelected; - (NSString*)description { return [NSString stringWithFormat:@"value:%f, percentage:%0.0f, start:%f, end:%f", _value, _percentage, _startAngle/M_PI*180, _endAngle/M_PI*180]; } + (BOOL)needsDisplayForKey:(NSString *)key { if ([key isEqualToString:@"startAngle"] || [key isEqualToString:@"endAngle"]) { return YES; } else { return [super needsDisplayForKey:key]; } } - (id)initWithLayer:(id)layer { if (self = [super initWithLayer:layer]) { if ([layer isKindOfClass:[SliceLayer class]]) { self.startAngle = [(SliceLayer *)layer startAngle]; self.endAngle = [(SliceLayer *)layer endAngle]; } } return self; } - (void)createArcAnimationForKey:(NSString *)key fromValue:(NSNumber *)from toValue:(NSNumber *)to Delegate:(id)delegate { CABasicAnimation *arcAnimation = [CABasicAnimation animationWithKeyPath:key]; NSNumber *currentAngle = [[self presentationLayer] valueForKey:key]; if(!currentAngle) currentAngle = from; [arcAnimation setFromValue:currentAngle]; [arcAnimation setToValue:to]; [arcAnimation setDelegate:delegate]; [arcAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]]; [self addAnimation:arcAnimation forKey:key]; [self setValue:to forKey:key]; } @end @interface XYPieChart (Private) - (void)updateTimerFired:(NSTimer *)timer; - (SliceLayer *)createSliceLayer; - (CGSize)sizeThatFitsString:(NSString *)string; - (void)updateLabelForLayer:(SliceLayer *)pieLayer value:(CGFloat)value; - (void)notifyDelegateOfSelectionChangeFrom:(NSUInteger)previousSelection to:(NSUInteger)newSelection; @end @implementation XYPieChart { NSInteger _selectedSliceIndex; //pie view, contains all slices UIView *_pieView; //animation control NSTimer *_animationTimer; NSMutableArray *_animations; } static NSUInteger kDefaultSliceZOrder = 100; @synthesize dataSource = _dataSource; @synthesize delegate = _delegate; @synthesize startPieAngle = _startPieAngle; @synthesize animationSpeed = _animationSpeed; @synthesize pieCenter = _pieCenter; @synthesize pieRadius = _pieRadius; @synthesize showLabel = _showLabel; @synthesize labelFont = _labelFont; @synthesize labelColor = _labelColor; @synthesize labelShadowColor = _labelShadowColor; @synthesize labelRadius = _labelRadius; @synthesize selectedSliceStroke = _selectedSliceStroke; @synthesize selectedSliceOffsetRadius = _selectedSliceOffsetRadius; @synthesize showPercentage = _showPercentage; static CGPathRef CGPathCreateArc(CGPoint center, CGFloat radius, CGFloat startAngle, CGFloat endAngle) { CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, center.x, center.y); CGPathAddArc(path, NULL, center.x, center.y, radius, startAngle, endAngle, 0); CGPathCloseSubpath(path); return path; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor clearColor]; _pieView = [[UIView alloc] initWithFrame:frame]; [_pieView setBackgroundColor:[UIColor clearColor]]; [self addSubview:_pieView]; _selectedSliceIndex = -1; _animations = [[NSMutableArray alloc] init]; _animationSpeed = 0.5; _startPieAngle = M_PI_2*3; _selectedSliceStroke = 3.0; self.pieRadius = MIN(frame.size.width/2, frame.size.height/2) - 10; self.pieCenter = CGPointMake(frame.size.width/2, frame.size.height/2); self.labelFont = [UIFont boldSystemFontOfSize:MAX((int)self.pieRadius/10, 5)]; _labelColor = [UIColor whiteColor]; _labelRadius = _pieRadius/2; _selectedSliceOffsetRadius = MAX(10, _pieRadius/10); _showLabel = YES; _showPercentage = YES; } return self; } - (id)initWithFrame:(CGRect)frame Center:(CGPoint)center Radius:(CGFloat)radius { self = [self initWithFrame:frame]; if (self) { self.pieCenter = center; self.pieRadius = radius; } return self; } - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if(self) { _pieView = [[UIView alloc] initWithFrame:self.bounds]; [_pieView setBackgroundColor:[UIColor clearColor]]; [self insertSubview:_pieView atIndex:0]; _selectedSliceIndex = -1; _animations = [[NSMutableArray alloc] init]; _animationSpeed = 0.5; _startPieAngle = M_PI_2*3; _selectedSliceStroke = 3.0; CGRect bounds = [[self layer] bounds]; self.pieRadius = MIN(bounds.size.width/2, bounds.size.height/2) - 10; self.pieCenter = CGPointMake(bounds.size.width/2, bounds.size.height/2); self.labelFont = [UIFont boldSystemFontOfSize:MAX((int)self.pieRadius/10, 5)]; _labelColor = [UIColor whiteColor]; _labelRadius = _pieRadius/2; _selectedSliceOffsetRadius = MAX(10, _pieRadius/10); _showLabel = YES; _showPercentage = YES; } return self; } - (void)setPieCenter:(CGPoint)pieCenter { [_pieView setCenter:pieCenter]; _pieCenter = CGPointMake(_pieView.frame.size.width/2, _pieView.frame.size.height/2); } - (void)setPieRadius:(CGFloat)pieRadius { _pieRadius = pieRadius; CGPoint origin = _pieView.frame.origin; CGRect frame = CGRectMake(origin.x+_pieCenter.x-pieRadius, origin.y+_pieCenter.y-pieRadius, pieRadius*2, pieRadius*2); _pieCenter = CGPointMake(frame.size.width/2, frame.size.height/2); [_pieView setFrame:frame]; [_pieView.layer setCornerRadius:_pieRadius]; } - (void)setPieBackgroundColor:(UIColor *)color { [_pieView setBackgroundColor:color]; } #pragma mark - manage settings - (void)setShowPercentage:(BOOL)showPercentage { _showPercentage = showPercentage; for(SliceLayer *layer in _pieView.layer.sublayers) { CATextLayer *textLayer = [[layer sublayers] objectAtIndex:0]; [textLayer setHidden:!_showLabel]; if(!_showLabel) return; NSString *label; if(_showPercentage) label = [NSString stringWithFormat:@"%0.0f", layer.percentage*100]; else label = (layer.text)?layer.text:[NSString stringWithFormat:@"%0.0f", layer.value]; CGSize size = [label sizeWithFont:self.labelFont]; if(M_PI*2*_labelRadius*layer.percentage < MAX(size.width,size.height)) { [textLayer setString:@""]; } else { [textLayer setString:label]; [textLayer setBounds:CGRectMake(0, 0, size.width, size.height)]; } } } #pragma mark - Pie Reload Data With Animation - (void)reloadData { if (_dataSource) { CALayer *parentLayer = [_pieView layer]; NSArray *slicelayers = [parentLayer sublayers]; _selectedSliceIndex = -1; [slicelayers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { SliceLayer *layer = (SliceLayer *)obj; if(layer.isSelected) [self setSliceDeselectedAtIndex:idx]; }]; double startToAngle = 0.0; double endToAngle = startToAngle; NSUInteger sliceCount = [_dataSource numberOfSlicesInPieChart:self]; double sum = 0.0; double values[sliceCount]; for (int index = 0; index < sliceCount; index++) { values[index] = [_dataSource pieChart:self valueForSliceAtIndex:index]; sum += values[index]; } double angles[sliceCount]; for (int index = 0; index < sliceCount; index++) { double div; if (sum == 0) div = 0; else div = values[index] / sum; angles[index] = M_PI * 2 * div; } [CATransaction begin]; [CATransaction setAnimationDuration:_animationSpeed]; [_pieView setUserInteractionEnabled:NO]; __block NSMutableArray *layersToRemove = nil; BOOL isOnStart = ([slicelayers count] == 0 && sliceCount); NSInteger diff = sliceCount - [slicelayers count]; layersToRemove = [NSMutableArray arrayWithArray:slicelayers]; BOOL isOnEnd = ([slicelayers count] && (sliceCount == 0 || sum <= 0)); if(isOnEnd) { for(SliceLayer *layer in _pieView.layer.sublayers){ [self updateLabelForLayer:layer value:0]; [layer createArcAnimationForKey:@"startAngle" fromValue:[NSNumber numberWithDouble:_startPieAngle] toValue:[NSNumber numberWithDouble:_startPieAngle] Delegate:self]; [layer createArcAnimationForKey:@"endAngle" fromValue:[NSNumber numberWithDouble:_startPieAngle] toValue:[NSNumber numberWithDouble:_startPieAngle] Delegate:self]; } [CATransaction commit]; return; } for(int index = 0; index < sliceCount; index ++) { SliceLayer *layer; double angle = angles[index]; endToAngle += angle; double startFromAngle = _startPieAngle + startToAngle; double endFromAngle = _startPieAngle + endToAngle; if( index >= [slicelayers count] ) { layer = [self createSliceLayer]; if (isOnStart) startFromAngle = endFromAngle = _startPieAngle; [parentLayer addSublayer:layer]; diff--; } else { SliceLayer *onelayer = [slicelayers objectAtIndex:index]; if(diff == 0 || onelayer.value == (CGFloat)values[index]) { layer = onelayer; [layersToRemove removeObject:layer]; } else if(diff > 0) { layer = [self createSliceLayer]; [parentLayer insertSublayer:layer atIndex:index]; diff--; } else if(diff < 0) { while(diff < 0) { [onelayer removeFromSuperlayer]; [parentLayer addSublayer:onelayer]; diff++; onelayer = [slicelayers objectAtIndex:index]; if(onelayer.value == (CGFloat)values[index] || diff == 0) { layer = onelayer; [layersToRemove removeObject:layer]; break; } } } } layer.value = values[index]; layer.percentage = (sum)?layer.value/sum:0; UIColor *color = nil; if([_dataSource respondsToSelector:@selector(pieChart:colorForSliceAtIndex:)]) { color = [_dataSource pieChart:self colorForSliceAtIndex:index]; } if(!color) { color = [UIColor colorWithHue:((index/8)%20)/20.0+0.02 saturation:(index%8+3)/10.0 brightness:91/100.0 alpha:1]; } [layer setFillColor:color.CGColor]; if([_dataSource respondsToSelector:@selector(pieChart:textForSliceAtIndex:)]) { layer.text = [_dataSource pieChart:self textForSliceAtIndex:index]; } [self updateLabelForLayer:layer value:values[index]]; [layer createArcAnimationForKey:@"startAngle" fromValue:[NSNumber numberWithDouble:startFromAngle] toValue:[NSNumber numberWithDouble:startToAngle+_startPieAngle] Delegate:self]; [layer createArcAnimationForKey:@"endAngle" fromValue:[NSNumber numberWithDouble:endFromAngle] toValue:[NSNumber numberWithDouble:endToAngle+_startPieAngle] Delegate:self]; startToAngle = endToAngle; } [CATransaction setDisableActions:YES]; for(SliceLayer *layer in layersToRemove) { [layer setFillColor:[self backgroundColor].CGColor]; [layer setDelegate:nil]; [layer setZPosition:0]; CATextLayer *textLayer = (CATextLayer *) [[layer sublayers] objectAtIndex:0]; [textLayer setHidden:YES]; } [layersToRemove enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [obj removeFromSuperlayer]; }]; [layersToRemove removeAllObjects]; for(SliceLayer *layer in _pieView.layer.sublayers) { [layer setZPosition:kDefaultSliceZOrder]; } [_pieView setUserInteractionEnabled:YES]; [CATransaction setDisableActions:NO]; [CATransaction commit]; } } #pragma mark - Animation Delegate + Run Loop Timer - (void)updateTimerFired:(NSTimer *)timer; { CALayer *parentLayer = [_pieView layer]; NSArray *pieLayers = [parentLayer sublayers]; [pieLayers enumerateObjectsUsingBlock:^(CAShapeLayer * obj, NSUInteger idx, BOOL *stop) { NSNumber *presentationLayerStartAngle = [[obj presentationLayer] valueForKey:@"startAngle"]; CGFloat interpolatedStartAngle = [presentationLayerStartAngle doubleValue]; NSNumber *presentationLayerEndAngle = [[obj presentationLayer] valueForKey:@"endAngle"]; CGFloat interpolatedEndAngle = [presentationLayerEndAngle doubleValue]; CGPathRef path = CGPathCreateArc(_pieCenter, _pieRadius, interpolatedStartAngle, interpolatedEndAngle); [obj setPath:path]; CFRelease(path); { CALayer *labelLayer = [[obj sublayers] objectAtIndex:0]; CGFloat interpolatedMidAngle = (interpolatedEndAngle + interpolatedStartAngle) / 2; [CATransaction setDisableActions:YES]; [labelLayer setPosition:CGPointMake(_pieCenter.x + (_labelRadius * cos(interpolatedMidAngle)), _pieCenter.y + (_labelRadius * sin(interpolatedMidAngle)))]; [CATransaction setDisableActions:NO]; } }]; } - (void)animationDidStart:(CAAnimation *)anim { if (_animationTimer == nil) { static float timeInterval = 1.0/60.0; // Run the animation timer on the main thread. // We want to allow the user to interact with the UI while this timer is running. // If we run it on this thread, the timer will be halted while the user is touching the screen (that's why the chart was disappearing in our collection view). _animationTimer= [NSTimer timerWithTimeInterval:timeInterval target:self selector:@selector(updateTimerFired:) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:_animationTimer forMode:NSRunLoopCommonModes]; } [_animations addObject:anim]; } - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)animationCompleted { [_animations removeObject:anim]; if ([_animations count] == 0) { [_animationTimer invalidate]; _animationTimer = nil; } } #pragma mark - Touch Handing (Selection Notification) - (NSInteger)getCurrentSelectedOnTouch:(CGPoint)point { __block NSUInteger selectedIndex = -1; CGAffineTransform transform = CGAffineTransformIdentity; CALayer *parentLayer = [_pieView layer]; NSArray *pieLayers = [parentLayer sublayers]; [pieLayers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { SliceLayer *pieLayer = (SliceLayer *)obj; CGPathRef path = [pieLayer path]; if (CGPathContainsPoint(path, &transform, point, 0)) { [pieLayer setLineWidth:_selectedSliceStroke]; [pieLayer setStrokeColor:[UIColor whiteColor].CGColor]; [pieLayer setLineJoin:kCALineJoinBevel]; [pieLayer setZPosition:MAXFLOAT]; selectedIndex = idx; } else { [pieLayer setZPosition:kDefaultSliceZOrder]; [pieLayer setLineWidth:0.0]; } }]; return selectedIndex; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self touchesMoved:touches withEvent:event]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint point = [touch locationInView:_pieView]; [self getCurrentSelectedOnTouch:point]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint point = [touch locationInView:_pieView]; NSInteger selectedIndex = [self getCurrentSelectedOnTouch:point]; [self notifyDelegateOfSelectionChangeFrom:_selectedSliceIndex to:selectedIndex]; [self touchesCancelled:touches withEvent:event]; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { CALayer *parentLayer = [_pieView layer]; NSArray *pieLayers = [parentLayer sublayers]; for (SliceLayer *pieLayer in pieLayers) { [pieLayer setZPosition:kDefaultSliceZOrder]; [pieLayer setLineWidth:0.0]; } } #pragma mark - Selection Notification - (void)notifyDelegateOfSelectionChangeFrom:(NSUInteger)previousSelection to:(NSUInteger)newSelection { if (previousSelection != newSelection){ if(previousSelection != -1){ NSUInteger tempPre = previousSelection; if ([_delegate respondsToSelector:@selector(pieChart:willDeselectSliceAtIndex:)]) [_delegate pieChart:self willDeselectSliceAtIndex:tempPre]; [self setSliceDeselectedAtIndex:tempPre]; previousSelection = newSelection; if([_delegate respondsToSelector:@selector(pieChart:didDeselectSliceAtIndex:)]) [_delegate pieChart:self didDeselectSliceAtIndex:tempPre]; } if (newSelection != -1){ if([_delegate respondsToSelector:@selector(pieChart:willSelectSliceAtIndex:)]) [_delegate pieChart:self willSelectSliceAtIndex:newSelection]; [self setSliceSelectedAtIndex:newSelection]; _selectedSliceIndex = newSelection; if([_delegate respondsToSelector:@selector(pieChart:didSelectSliceAtIndex:)]) [_delegate pieChart:self didSelectSliceAtIndex:newSelection]; } }else if (newSelection != -1){ SliceLayer *layer = [_pieView.layer.sublayers objectAtIndex:newSelection]; if(_selectedSliceOffsetRadius > 0 && layer){ if (layer.isSelected) { if ([_delegate respondsToSelector:@selector(pieChart:willDeselectSliceAtIndex:)]) [_delegate pieChart:self willDeselectSliceAtIndex:newSelection]; [self setSliceDeselectedAtIndex:newSelection]; if (newSelection != -1 && [_delegate respondsToSelector:@selector(pieChart:didDeselectSliceAtIndex:)]) [_delegate pieChart:self didDeselectSliceAtIndex:newSelection]; previousSelection = _selectedSliceIndex = -1; }else{ if ([_delegate respondsToSelector:@selector(pieChart:willSelectSliceAtIndex:)]) [_delegate pieChart:self willSelectSliceAtIndex:newSelection]; [self setSliceSelectedAtIndex:newSelection]; previousSelection = _selectedSliceIndex = newSelection; if (newSelection != -1 && [_delegate respondsToSelector:@selector(pieChart:didSelectSliceAtIndex:)]) [_delegate pieChart:self didSelectSliceAtIndex:newSelection]; } } } } #pragma mark - Selection Programmatically Without Notification - (void)setSliceSelectedAtIndex:(NSInteger)index { if(_selectedSliceOffsetRadius <= 0) return; SliceLayer *layer = [_pieView.layer.sublayers objectAtIndex:index]; if (layer && !layer.isSelected) { CGPoint currPos = layer.position; double middleAngle = (layer.startAngle + layer.endAngle)/2.0; CGPoint newPos = CGPointMake(currPos.x + _selectedSliceOffsetRadius*cos(middleAngle), currPos.y + _selectedSliceOffsetRadius*sin(middleAngle)); layer.position = newPos; layer.isSelected = YES; } } - (void)setSliceDeselectedAtIndex:(NSInteger)index { if(_selectedSliceOffsetRadius <= 0) return; SliceLayer *layer = [_pieView.layer.sublayers objectAtIndex:index]; if (layer && layer.isSelected) { layer.position = CGPointMake(0, 0); layer.isSelected = NO; } } #pragma mark - Pie Layer Creation Method - (SliceLayer *)createSliceLayer { SliceLayer *pieLayer = [SliceLayer layer]; [pieLayer setZPosition:0]; [pieLayer setStrokeColor:NULL]; CATextLayer *textLayer = [CATextLayer layer]; textLayer.contentsScale = [[UIScreen mainScreen] scale]; CGFontRef font = nil; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) { font = CGFontCreateCopyWithVariations((__bridge CGFontRef)(self.labelFont), (__bridge CFDictionaryRef)(@{})); } else { font = CGFontCreateWithFontName((__bridge CFStringRef)[self.labelFont fontName]); } if (font) { [textLayer setFont:font]; CFRelease(font); } [textLayer setFontSize:self.labelFont.pointSize]; [textLayer setAnchorPoint:CGPointMake(0.5, 0.5)]; [textLayer setAlignmentMode:kCAAlignmentCenter]; [textLayer setBackgroundColor:[UIColor clearColor].CGColor]; [textLayer setForegroundColor:self.labelColor.CGColor]; if (self.labelShadowColor) { [textLayer setShadowColor:self.labelShadowColor.CGColor]; [textLayer setShadowOffset:CGSizeZero]; [textLayer setShadowOpacity:1.0f]; [textLayer setShadowRadius:2.0f]; } CGSize size = [@"0" sizeWithFont:self.labelFont]; [CATransaction setDisableActions:YES]; [textLayer setFrame:CGRectMake(0, 0, size.width, size.height)]; [textLayer setPosition:CGPointMake(_pieCenter.x + (_labelRadius * cos(0)), _pieCenter.y + (_labelRadius * sin(0)))]; [CATransaction setDisableActions:NO]; [pieLayer addSublayer:textLayer]; return pieLayer; } - (void)updateLabelForLayer:(SliceLayer *)pieLayer value:(CGFloat)value { CATextLayer *textLayer = (CATextLayer *)[[pieLayer sublayers] objectAtIndex:0]; [textLayer setHidden:!_showLabel]; if(!_showLabel) return; NSString *label; if(_showPercentage) label = [NSString stringWithFormat:@"%0.0f", pieLayer.percentage*100]; else label = (pieLayer.text)?pieLayer.text:[NSString stringWithFormat:@"%0.0f", value]; CGSize size = [label sizeWithFont:self.labelFont]; [CATransaction setDisableActions:YES]; if(M_PI*2*_labelRadius*pieLayer.percentage < MAX(size.width,size.height) || value <= 0) { [textLayer setString:@""]; } else { [textLayer setString:label]; [textLayer setBounds:CGRectMake(0, 0, size.width, size.height)]; } [CATransaction setDisableActions:NO]; } @end
提供两组假数据
self.slices = [[NSArray alloc ] init]; self.slices = @[@"0.24",@"0.36",@"0.05",@"0.14",@"0.10",@"0.11"]; self.showTexts = [[NSArray alloc] init]; self.showTexts = @[@"24%",@"36%",@"5%",@"14%",@"10%",@"11%"]; options = @[@{@"content" :@"0 ~ 61",@"optionid":@"A"},@{@"content" :@"61 ~ 120",@"optionid":@"B"},@{@"content" :@"121 ~ 180",@"optionid":@"C"},@{@"content" :@"181 ~ 240",@"optionid":@"D"},@{@"content" :@"241 ~ 300",@"optionid":@"E"},@{@"content" :@"301 ~ 360",@"optionid":@"F"}];
//为扇形视图做准备 self.selectResult.delegate = self; self.selectResult.dataSource = self; self.selectResult.backgroundColor = [UIColor clearColor]; self.selectResult.showPercentage = NO; [self.selectResult setPieCenter:CGPointMake(80, 80)]; //写一个数组 盛放需要的颜色 self.sliceColors =[NSMutableArray arrayWithObjects: [UIColor colorWithRed:246/255.0 green:155/255.0 blue:0/255.0 alpha:1], [UIColor colorWithRed:129/255.0 green:195/255.0 blue:29/255.0 alpha:1], [UIColor colorWithRed:62/255.0 green:173/255.0 blue:219/255.0 alpha:1], [UIColor colorWithRed:229/255.0 green:66/255.0 blue:115/255.0 alpha:1], [UIColor colorWithRed:148/255.0 green:141/255.0 blue:139/255.0 alpha:1], [UIColor colorWithRed:120/255.0 green:80/255.0 blue:149/255.0 alpha:1],nil];
实现代理方法
#pragma mark - XYPieChart Data Source - (NSUInteger)numberOfSlicesInPieChart:(XYPieChart *)pieChart { return self.slices.count; } - (CGFloat)pieChart:(XYPieChart *)pieChart valueForSliceAtIndex:(NSUInteger)index { return [[self.slices objectAtIndex:index] floatValue]; } - (UIColor *)pieChart:(XYPieChart *)pieChart colorForSliceAtIndex:(NSUInteger)index { return [self.sliceColors objectAtIndex:(index % self.sliceColors.count)]; } - (NSString *)pieChart:(XYPieChart *)pieChart textForSliceAtIndex:(NSUInteger)index{ NSString *text = [self.showTexts objectAtIndex: (index % self.showTexts.count) ]; NSLog(@"text index : %ld %@", index, text); return text; } #pragma mark - XYPieChart Delegate - (void)pieChart:(XYPieChart *)pieChart willSelectSliceAtIndex:(NSUInteger)index { NSLog(@"will select slice at index %ld",index); } - (void)pieChart:(XYPieChart *)pieChart willDeselectSliceAtIndex:(NSUInteger)index { NSLog(@"will deselect slice at index %ld",index); } - (void)pieChart:(XYPieChart *)pieChart didDeselectSliceAtIndex:(NSUInteger)index { NSLog(@"did deselect slice at index %ld",index); } - (void)pieChart:(XYPieChart *)pieChart didSelectSliceAtIndex:(NSUInteger)index { NSLog(@"did select slice at index %ld",index); }
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.selectResult reloadData]; }