Repository: SeJasonWang/SCChart Branch: master Commit: ef5fab58ac11 Files: 46 Total size: 131.9 KB Directory structure: gitextract_g0t4jqgw/ ├── .gitignore ├── README.md ├── SCChart/ │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj/ │ │ └── LaunchScreen.xib │ ├── Images.xcassets/ │ │ └── AppIcon.appiconset/ │ │ └── Contents.json │ ├── Info.plist │ ├── SCBarCell.h │ ├── SCBarCell.m │ ├── SCChart/ │ │ ├── SCBar.h │ │ ├── SCBar.m │ │ ├── SCBarChart.h │ │ ├── SCBarChart.m │ │ ├── SCChart.h │ │ ├── SCChart.m │ │ ├── SCChartDelegate.h │ │ ├── SCChartLabel.h │ │ ├── SCChartLabel.m │ │ ├── SCCircleChart.h │ │ ├── SCCircleChart.m │ │ ├── SCColor.h │ │ ├── SCColor.m │ │ ├── SCGenericChart.h │ │ ├── SCGenericChart.m │ │ ├── SCLineChart.h │ │ ├── SCLineChart.m │ │ ├── SCPieChart.h │ │ ├── SCPieChart.m │ │ ├── SCPieChartDataItem.h │ │ ├── SCPieChartDataItem.m │ │ ├── SCTool.h │ │ ├── SCTool.m │ │ ├── UICountingLabel.h │ │ └── UICountingLabel.m │ ├── SCChartCell.h │ ├── SCChartCell.m │ ├── SCCircleCell.h │ ├── SCCircleCell.m │ ├── SCPieCell.h │ ├── SCPieCell.m │ ├── SCViewController.h │ ├── SCViewController.m │ └── main.m ├── SCChart.xcodeproj/ │ └── project.pbxproj └── SCChartTests/ ├── Info.plist └── SCChartTests.m ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ project.xcworkspace xcuserdata *.xccheckout config.plist *.swp .DS_Store Build ================================================ FILE: README.md ================================================ ### 如何使用-SCChart ![icon](https://img.alicdn.com/imgextra/i2/135480037/TB2E0ubkpXXXXaCXXXXXXXXXXXX_!!135480037.gif) ####导入主头文件 #import "SCChart.h" ##### 一.折线图和柱状图 1.实例化 ( SCChartLineStyle | SCChartBarStyle ) SCChart *chartView = [[SCChart alloc] initwithSCChartDataFrame:CGRectMake(10, 10, [UIScreen mainScreen].bounds.size.width - 20, 150) withSource:self withStyle:SCChartLineStyle]; 2.设置横坐标标题 - (NSArray *)SCChart_xLableArray:(SCChart *)chart { return 横坐标数组; } 3.设置数值(多重数组, 纵坐标标题动态计算) - (NSArray *)SCChart_yValueArray:(SCChart *)chart { return @[数组1,数组2]; } 4.设置折现颜色 - (NSArray *)SCChart_ColorArray:(SCChart *)chart { return @[SCBlue,SCRed,SCGreen]; } 5.是否显示间隔线条(折线图专用) - (BOOL)SCChart:(SCChart *)chart ShowHorizonLineAtIndex:(NSInteger)index { return YES; } ##### 二.圆环图 1.实例化 SCCircleChart *chartView = [[SCCircleChart alloc] initWithFrame:CGRectMake(0, (self.frame.size.height-100)/2, SCREEN_WIDTH, 100.0) total:@100 current:@60 clockwise:YES]; 2.设置圆环颜色 [chartView setStrokeColor:SCBlue]; 3.画线 [chartView strokeChart]; ##### 三.圆饼图 1.设置数值并实例化 NSArray *items = @[[SCPieChartDataItem dataItemWithValue:10 color:SCRed description:@"A"], [SCPieChartDataItem dataItemWithValue:20 color:SCBlue description:@"B"], [SCPieChartDataItem dataItemWithValue:40 color:SCGreen description:@"C"], ]; SCPieChart *chartView = [[SCPieChart alloc] initWithFrame:CGRectMake((SCREEN_WIDTH-150)/2, (self.frame.size.height-150)/2, 150.0, 150.0) items:items]; 2.设置描述文字 chartView.descriptionTextColor = [UIColor whiteColor]; chartView.descriptionTextFont = [UIFont fontWithName:@"Avenir-Medium" size:12.0]; 3.画线 [chartView strokeChart]; ================================================ FILE: SCChart/AppDelegate.h ================================================ // // AppDelegate.h // SCChart // // Created by 2014-763 on 15/3/13. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @end ================================================ FILE: SCChart/AppDelegate.m ================================================ // // AppDelegate.m // SCChart // // Created by 2014-763 on 15/3/13. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "AppDelegate.h" #import "SCViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.rootViewController = [[SCViewController alloc] init]; [self.window makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } @end ================================================ FILE: SCChart/Base.lproj/LaunchScreen.xib ================================================ ================================================ FILE: SCChart/Images.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "1x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: SCChart/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier com.meilishuo.bizfe.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: SCChart/SCBarCell.h ================================================ // // DCBarCell.h // UUChart // // Created by 2014-763 on 15/3/13. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import @interface SCBarCell : UITableViewCell - (void)configUI:(NSIndexPath *)indexPath; @end ================================================ FILE: SCChart/SCBarCell.m ================================================ // // DCBarCell.m // UUChart // // Created by 2014-763 on 15/3/13. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCBarCell.h" #import "SCChart.h" @interface SCBarCell () { NSIndexPath *path; SCChart *chartView; } @end @implementation SCBarCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; [btn setTitle:@"点击刷新数据" forState:UIControlStateNormal]; btn.titleLabel.font = [UIFont systemFontOfSize:12.0];; [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; btn.frame = CGRectMake(0, 0, SCREEN_WIDTH, 27); [btn addTarget:self action:@selector(btnPressed:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:btn]; } return self; } - (void)btnPressed:(id)sender { [chartView strokeChart]; } - (void)configUI:(NSIndexPath *)indexPath { if (chartView) { [chartView removeFromSuperview]; chartView = nil; } path = indexPath; chartView = [[SCChart alloc] initwithSCChartDataFrame:CGRectMake(10, (self.frame.size.height-150)/2, [UIScreen mainScreen].bounds.size.width - 20, 150) withSource:self withStyle:SCChartBarStyle]; [chartView showInView:self.contentView]; } - (NSArray *)getXTitles:(int)num { NSMutableArray *xTitles = [NSMutableArray array]; for (int i=0; i @interface SCBar : UIView @property (nonatomic) float grade; @property (nonatomic,strong) CAShapeLayer * chartLine; @property (nonatomic, strong) UIColor * barColor; @end ================================================ FILE: SCChart/SCChart/SCBar.m ================================================ // // UUBar.m // UUChartDemo // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCBar.h" #import "SCColor.h" @implementation SCBar - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code _chartLine = [CAShapeLayer layer]; _chartLine.lineCap = kCALineCapSquare; _chartLine.fillColor = [[UIColor whiteColor] CGColor]; _chartLine.lineWidth = self.frame.size.width; _chartLine.strokeEnd = 0.0; self.clipsToBounds = YES; [self.layer addSublayer:_chartLine]; // self.layer.cornerRadius = 2.0; // 直接设置layer会造成卡顿 } return self; } -(void)setGrade:(float)grade { if (grade==0) return; _grade = grade; UIBezierPath *progressline = [UIBezierPath bezierPath]; [progressline moveToPoint:CGPointMake(self.frame.size.width/2.0, self.frame.size.height+30)]; [progressline addLineToPoint:CGPointMake(self.frame.size.width/2.0, (1 - grade) * self.frame.size.height+15)]; [progressline setLineWidth:1.0]; [progressline setLineCapStyle:kCGLineCapSquare]; _chartLine.path = progressline.CGPath; if (_barColor) { _chartLine.strokeColor = [_barColor CGColor]; }else{ _chartLine.strokeColor = [SCGreen CGColor]; } CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; pathAnimation.duration = 1.5; pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; pathAnimation.toValue = [NSNumber numberWithFloat:1.0f]; pathAnimation.autoreverses = NO; [_chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; _chartLine.strokeEnd = 2.0; } - (void)drawRect:(CGRect)rect { //Draw BG CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextFillRect(context, rect); } @end ================================================ FILE: SCChart/SCChart/SCBarChart.h ================================================ // // UUBarChart.h // UUChartDemo // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import #import "SCColor.h" #define chartMargin 10 #define xLabelMargin 15 #define yLabelMargin 15 #define UULabelHeight 10 #define UUYLabelwidth 30 @interface SCBarChart : UIView /** * This method will call and troke the line in animation */ -(void)strokeChart; @property (strong, nonatomic) NSArray * xLabels; @property (strong, nonatomic) NSArray * yLabels; @property (strong, nonatomic) NSArray * yValues; @property (nonatomic) CGFloat xLabelWidth; @property (nonatomic) float yValueMax; @property (nonatomic) float yValueMin; @property (nonatomic, assign) BOOL showRange; @property (nonatomic, assign) CGRange chooseRange; @property (nonatomic, strong) NSArray * colors; @end ================================================ FILE: SCChart/SCChart/SCBarChart.m ================================================ // // UUBarChart.m // UUChartDemo // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCBarChart.h" #import "SCChartLabel.h" #import "SCBar.h" #import "SCTool.h" @interface SCBarChart () { UIScrollView *myScrollView; } @end @implementation SCBarChart - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.clipsToBounds = YES; myScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(UUYLabelwidth, 0, frame.size.width-UUYLabelwidth, frame.size.height)]; [self addSubview:myScrollView]; } return self; } -(void)setYValues:(NSArray *)yValues { _yValues = yValues; [self setYLabels:yValues]; } -(void)setYLabels:(NSArray *)yLabels { CGFloat max = 0; CGFloat min = 1000000000; NSInteger rowCount = 0; // 自动计算每个图表适合的行数 for (NSArray * ary in yLabels) { for (NSString *valueString in ary) { CGFloat value = [valueString floatValue]; if (value > max) { max = value; } if (value < min) { min = value; } } } if (self.showRange) { _yValueMin = min; }else{ _yValueMin = 0; } _yValueMax = max; if (_chooseRange.max!=_chooseRange.min) { // 自定义数值范围 _yValueMax = _chooseRange.max; _yValueMin = _chooseRange.min; } else { // 自动计算数值范围和合适的行数 rowCount = [SCTool rowCountWithValueMax:_yValueMax] == 0 ? 5 : [SCTool rowCountWithValueMax:_yValueMax]; _yValueMax = [SCTool rangeMaxWithValueMax:_yValueMax] == 0 ? 100 : [SCTool rangeMaxWithValueMax:_yValueMax]; _yValueMin = 0; } float level = (_yValueMax-_yValueMin) /rowCount; // 每个区间的差值 CGFloat chartCavanHeight = self.frame.size.height - UULabelHeight*3; CGFloat levelHeight = chartCavanHeight /rowCount; // 每个区间的高度 for (int i=0; i=8) { num = 8; }else if (xLabels.count<=4){ num = 4; }else{ num = xLabels.count; } _xLabelWidth = myScrollView.frame.size.width/num; for (int i=0; i #import "SCChart.h" #import "SCColor.h" #import "SCLineChart.h" #import "SCBarChart.h" #import "SCCircleChart.h" #import "SCPieChart.h" //类型 typedef enum { SCChartLineStyle, SCChartBarStyle } SCChartStyle; @class SCChart; @protocol SCChartDataSource @required //横坐标标题数组 - (NSArray *)SCChart_xLableArray:(SCChart *)chart; //数值多重数组 - (NSArray *)SCChart_yValueArray:(SCChart *)chart; @optional //颜色数组 - (NSArray *)SCChart_ColorArray:(SCChart *)chart; //显示数值范围 - (CGRange)SCChartChooseRangeInLineChart:(SCChart *)chart; #pragma mark 折线图专享功能 //标记数值区域 - (CGRange)SCChartMarkRangeInLineChart:(SCChart *)chart; //判断显示横线条 - (BOOL)SCChart:(SCChart *)chart ShowHorizonLineAtIndex:(NSInteger)index; //判断显示最大最小值 - (BOOL)SCChart:(SCChart *)chart ShowMaxMinAtIndex:(NSInteger)index; @end @interface SCChart : UIView //是否自动显示范围 @property (nonatomic, assign) BOOL showRange; @property (assign) SCChartStyle chartStyle; -(id)initwithSCChartDataFrame:(CGRect)rect withSource:(id)dataSource withStyle:(SCChartStyle)style; - (void)showInView:(UIView *)view; -(void)strokeChart; @end ================================================ FILE: SCChart/SCChart/SCChart.m ================================================ // // UUChart.m // UUChart // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCChart.h" #define kRowMax 6 // 可支持最大行数 @interface SCChart () @property (strong, nonatomic) SCLineChart * lineChart; @property (strong, nonatomic) SCBarChart * barChart; @property (assign, nonatomic) id dataSource; @end @implementation SCChart -(id)initwithSCChartDataFrame:(CGRect)rect withSource:(id)dataSource withStyle:(SCChartStyle)style{ self.dataSource = dataSource; self.chartStyle = style; return [self initWithFrame:rect]; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.backgroundColor = [UIColor whiteColor]; self.clipsToBounds = NO; } return self; } -(void)setUpChart{ if (self.chartStyle == SCChartLineStyle) { [self.lineChart removeFromSuperview]; self.lineChart = nil; if(!_lineChart){ _lineChart = [[SCLineChart alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; [self addSubview:_lineChart]; } //选择标记范围 if ([self.dataSource respondsToSelector:@selector(SCChartMarkRangeInLineChart:)]) { [_lineChart setMarkRange:[self.dataSource SCChartMarkRangeInLineChart:self]]; } //选择显示范围 if ([self.dataSource respondsToSelector:@selector(SCChartChooseRangeInLineChart:)]) { [_lineChart setChooseRange:[self.dataSource SCChartChooseRangeInLineChart:self]]; } //显示颜色 if ([self.dataSource respondsToSelector:@selector(SCChart_ColorArray:)]) { [_lineChart setColors:[self.dataSource SCChart_ColorArray:self]]; } //显示横线 if ([self.dataSource respondsToSelector:@selector(SCChart:ShowHorizonLineAtIndex:)]) { NSMutableArray *showHorizonArray = [[NSMutableArray alloc]init]; for (int i=0; i0){ for (int i=0; i @protocol SCChartDelegate @optional /** * Callback method that gets invoked when the user taps on the chart line. */ - (void)userClickedOnLinePoint:(CGPoint)point lineIndex:(NSInteger)lineIndex; /** * Callback method that gets invoked when the user taps on a chart line key point. */ - (void)userClickedOnLineKeyPoint:(CGPoint)point lineIndex:(NSInteger)lineIndex pointIndex:(NSInteger)pointIndex; /** * Callback method that gets invoked when the user taps on a chart bar. */ - (void)userClickedOnBarAtIndex:(NSInteger)barIndex; - (void)userClickedOnPieIndexItem:(NSInteger)pieIndex; - (void)didUnselectPieItem; @end ================================================ FILE: SCChart/SCChart/SCChartLabel.h ================================================ // // PNChartLabel.h // PNChart // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import @interface SCChartLabel : UILabel @end ================================================ FILE: SCChart/SCChart/SCChartLabel.m ================================================ // // PNChartLabel.m // PNChart // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCChartLabel.h" #import "SCColor.h" @implementation SCChartLabel - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code [self setLineBreakMode:NSLineBreakByWordWrapping]; [self setMinimumScaleFactor:5.0f]; [self setNumberOfLines:1]; [self setFont:[UIFont boldSystemFontOfSize:9.0f]]; [self setTextColor: SCDeepGrey]; self.backgroundColor = [UIColor clearColor]; [self setTextAlignment:NSTextAlignmentCenter]; self.userInteractionEnabled = YES; } return self; } @end ================================================ FILE: SCChart/SCChart/SCCircleChart.h ================================================ // // PNCircleChart.h // PNChartDemo // // Created by kevinzhow on 13-11-30. // Copyright (c) 2013年 kevinzhow. All rights reserved. // #import #import "SCColor.h" #import "UICountingLabel.h" typedef NS_ENUM (NSUInteger, SCChartFormatType) { SCChartFormatTypePercent, SCChartFormatTypeDollar, SCChartFormatTypeNone }; #define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI) @interface SCCircleChart : UIView - (void)strokeChart; - (void)growChartByAmount:(NSNumber *)growAmount; - (void)updateChartByCurrent:(NSNumber *)current; - (void)updateChartByCurrent:(NSNumber *)current byTotal:(NSNumber *)total; - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise; - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise shadow:(BOOL)hasBackgroundShadow shadowColor:(UIColor *)backgroundShadowColor; - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise shadow:(BOOL)hasBackgroundShadow shadowColor:(UIColor *)backgroundShadowColor displayCountingLabel:(BOOL)displayCountingLabel; - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise shadow:(BOOL)hasBackgroundShadow shadowColor:(UIColor *)backgroundShadowColor displayCountingLabel:(BOOL)displayCountingLabel overrideLineWidth:(NSNumber *)overrideLineWidth; @property (strong, nonatomic) UICountingLabel *countingLabel; @property (nonatomic) UIColor *strokeColor; @property (nonatomic) UIColor *strokeColorGradientStart; @property (nonatomic) NSNumber *total; @property (nonatomic) NSNumber *current; @property (nonatomic) NSNumber *lineWidth; @property (nonatomic) NSTimeInterval duration; @property (nonatomic) SCChartFormatType chartType; @property (nonatomic, copy) NSString *format; @property (nonatomic) CAShapeLayer *circle; @property (nonatomic) CAShapeLayer *gradientMask; @property (nonatomic) CAShapeLayer *circleBackground; @property (nonatomic) BOOL displayCountingLabel; @end ================================================ FILE: SCChart/SCChart/SCCircleChart.m ================================================ // // PNCircleChart.m // PNChartDemo // // Created by kevinzhow on 13-11-30. // Copyright (c) 2013年 kevinzhow. All rights reserved. // #import "SCCircleChart.h" @interface SCCircleChart () @end @implementation SCCircleChart - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise { return [self initWithFrame:frame total:total current:current clockwise:clockwise shadow:NO shadowColor:[UIColor clearColor] displayCountingLabel:YES overrideLineWidth:@3.0f]; } - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise shadow:(BOOL)hasBackgroundShadow shadowColor:(UIColor *)backgroundShadowColor { return [self initWithFrame:frame total:total current:current clockwise:clockwise shadow:shadow shadowColor:backgroundShadowColor displayCountingLabel:YES overrideLineWidth:@3.0f]; } - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise shadow:(BOOL)hasBackgroundShadow shadowColor:(UIColor *)backgroundShadowColor displayCountingLabel:(BOOL)displayCountingLabel { return [self initWithFrame:frame total:total current:current clockwise:clockwise shadow:shadow shadowColor:SCGreen displayCountingLabel:displayCountingLabel overrideLineWidth:@3.0f]; } - (id)initWithFrame:(CGRect)frame total:(NSNumber *)total current:(NSNumber *)current clockwise:(BOOL)clockwise shadow:(BOOL)hasBackgroundShadow shadowColor:(UIColor *)backgroundShadowColor displayCountingLabel:(BOOL)displayCountingLabel overrideLineWidth:(NSNumber *)overrideLineWidth { self = [super initWithFrame:frame]; if (self) { _total = total; _current = current; _strokeColor = SCFreshGreen; _duration = 1.0; _chartType = SCChartFormatTypePercent; _displayCountingLabel = displayCountingLabel; CGFloat startAngle = clockwise ? -90.0f : 270.0f; CGFloat endAngle = clockwise ? -90.01f : 270.01f; _lineWidth = overrideLineWidth; UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width/2.0f, self.frame.size.height/2.0f) radius:(self.frame.size.height * 0.5) - ([_lineWidth floatValue]/2.0f) startAngle:DEGREES_TO_RADIANS(startAngle) endAngle:DEGREES_TO_RADIANS(endAngle) clockwise:clockwise]; _circle = [CAShapeLayer layer]; _circle.path = circlePath.CGPath; _circle.lineCap = kCALineCapRound; _circle.fillColor = [UIColor clearColor].CGColor; _circle.lineWidth = [_lineWidth floatValue]; _circle.zPosition = 1; _circleBackground = [CAShapeLayer layer]; _circleBackground.path = circlePath.CGPath; _circleBackground.lineCap = kCALineCapRound; _circleBackground.fillColor = [UIColor clearColor].CGColor; _circleBackground.lineWidth = [_lineWidth floatValue]; _circleBackground.strokeColor = (hasBackgroundShadow ? backgroundShadowColor.CGColor : [UIColor clearColor].CGColor); _circleBackground.strokeEnd = 1.0; _circleBackground.zPosition = -1; [self.layer addSublayer:_circle]; [self.layer addSublayer:_circleBackground]; _countingLabel = [[UICountingLabel alloc] initWithFrame:CGRectMake(0, 0, 100.0, 50.0)]; [_countingLabel setTextAlignment:NSTextAlignmentCenter]; [_countingLabel setFont:[UIFont boldSystemFontOfSize:12.0f]]; [_countingLabel setTextColor:[UIColor grayColor]]; [_countingLabel setBackgroundColor:[UIColor clearColor]]; [_countingLabel setCenter:CGPointMake(self.frame.size.width/2.0f, self.frame.size.height/2.0f)]; _countingLabel.numberOfLines = 0; _countingLabel.method = UILabelCountingMethodEaseInOut; if (_displayCountingLabel) { [self addSubview:_countingLabel]; } } return self; } - (void)strokeChart { // Add counting label if (_displayCountingLabel) { switch (self.chartType) { case SCChartFormatTypePercent: self.format = @"%d%%"; break; case SCChartFormatTypeDollar: self.format = @"$%d"; break; case SCChartFormatTypeNone: default: self.format = self.format ? self.format : @"%d"; break; } self.countingLabel.format = self.format; [self addSubview:self.countingLabel]; } // Add circle params _circle.lineWidth = [_lineWidth floatValue]; _circleBackground.lineWidth = [_lineWidth floatValue]; _circleBackground.strokeEnd = 1.0; _circle.strokeColor = _strokeColor.CGColor; // Add Animation CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; pathAnimation.duration = self.duration; pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; pathAnimation.fromValue = @0.0f; pathAnimation.toValue = @([_current floatValue] / [_total floatValue]); [_circle addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; _circle.strokeEnd = [_current floatValue] / [_total floatValue]; [_countingLabel countFrom:0 to:[_current floatValue]/([_total floatValue]/100.0) withDuration:self.duration]; // Check if user wants to add a gradient from the start color to the bar color if (_strokeColorGradientStart) { // Add gradient self.gradientMask = [CAShapeLayer layer]; self.gradientMask.fillColor = [[UIColor clearColor] CGColor]; self.gradientMask.strokeColor = [[UIColor blackColor] CGColor]; self.gradientMask.lineWidth = _circle.lineWidth; self.gradientMask.lineCap = kCALineCapRound; CGRect gradientFrame = CGRectMake(0, 0, 2*self.bounds.size.width, 2*self.bounds.size.height); self.gradientMask.frame = gradientFrame; self.gradientMask.path = _circle.path; CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.startPoint = CGPointMake(0.5,1.0); gradientLayer.endPoint = CGPointMake(0.5,0.0); gradientLayer.frame = gradientFrame; UIColor *endColor = (_strokeColor ? _strokeColor : [UIColor greenColor]); NSArray *colors = @[ (id)endColor.CGColor, (id)_strokeColorGradientStart.CGColor ]; gradientLayer.colors = colors; [gradientLayer setMask:self.gradientMask]; [_circle addSublayer:gradientLayer]; self.gradientMask.strokeEnd = [_current floatValue] / [_total floatValue]; [self.gradientMask addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; } } - (void)growChartByAmount:(NSNumber *)growAmount { NSNumber *updatedValue = [NSNumber numberWithFloat:[_current floatValue] + [growAmount floatValue]]; // Add animation [self updateChartByCurrent:updatedValue]; } -(void)updateChartByCurrent:(NSNumber *)current{ [self updateChartByCurrent:current byTotal:_total]; } -(void)updateChartByCurrent:(NSNumber *)current byTotal:(NSNumber *)total { // Add animation CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; pathAnimation.duration = self.duration; pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; pathAnimation.fromValue = @([_current floatValue] / [_total floatValue]); pathAnimation.toValue = @([current floatValue] / [total floatValue]); _circle.strokeEnd = [current floatValue] / [total floatValue]; if (_strokeColorGradientStart) { self.gradientMask.strokeEnd = _circle.strokeEnd; [self.gradientMask addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; } [_circle addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; if (_displayCountingLabel) { [self.countingLabel countFrom:fmin([_current floatValue], [_total floatValue]) to:fmin([current floatValue], [total floatValue]) withDuration:self.duration]; } _current = current; _total = total; } @end ================================================ FILE: SCChart/SCChart/SCColor.h ================================================ // // UUColor.h // UUChart // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import /* * System Versioning Preprocessor Macros */ #define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width) #define SCGrey [UIColor colorWithRed:246.0/255.0 green:246.0/255.0 blue:246.0/255.0 alpha:1.0f] #define SCLightBlue [UIColor colorWithRed:94.0/255.0 green:147.0/255.0 blue:196.0/255.0 alpha:1.0f] #define SCGreen [UIColor colorWithRed:77.0/255.0 green:186.0/255.0 blue:122.0/255.0 alpha:1.0f] #define SCTitleColor [UIColor colorWithRed:0.0/255.0 green:189.0/255.0 blue:113.0/255.0 alpha:1.0f] #define SCButtonGrey [UIColor colorWithRed:141.0/255.0 green:141.0/255.0 blue:141.0/255.0 alpha:1.0f] #define SCFreshGreen [UIColor colorWithRed:77.0/255.0 green:196.0/255.0 blue:122.0/255.0 alpha:1.0f] #define SCRed [UIColor colorWithRed:245.0/255.0 green:94.0/255.0 blue:78.0/255.0 alpha:1.0f] #define SCMauve [UIColor colorWithRed:88.0/255.0 green:75.0/255.0 blue:103.0/255.0 alpha:1.0f] #define SCBrown [UIColor colorWithRed:119.0/255.0 green:107.0/255.0 blue:95.0/255.0 alpha:1.0f] #define SCBlue [UIColor colorWithRed:82.0/255.0 green:116.0/255.0 blue:188.0/255.0 alpha:1.0f] #define SCDarkBlue [UIColor colorWithRed:121.0/255.0 green:134.0/255.0 blue:142.0/255.0 alpha:1.0f] #define SCYellow [UIColor colorWithRed:242.0/255.0 green:197.0/255.0 blue:117.0/255.0 alpha:1.0f] #define SCWhite [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0f] #define SCDeepGrey [UIColor colorWithRed:99.0/255.0 green:99.0/255.0 blue:99.0/255.0 alpha:1.0f] #define SCPinkGrey [UIColor colorWithRed:200.0/255.0 green:193.0/255.0 blue:193.0/255.0 alpha:1.0f] #define SCHealYellow [UIColor colorWithRed:245.0/255.0 green:242.0/255.0 blue:238.0/255.0 alpha:1.0f] #define SCLightGrey [UIColor colorWithRed:225.0/255.0 green:225.0/255.0 blue:225.0/255.0 alpha:1.0f] #define SCCleanGrey [UIColor colorWithRed:251.0/255.0 green:251.0/255.0 blue:251.0/255.0 alpha:1.0f] #define SCLightYellow [UIColor colorWithRed:241.0/255.0 green:240.0/255.0 blue:240.0/255.0 alpha:1.0f] #define SCDarkYellow [UIColor colorWithRed:152.0/255.0 green:150.0/255.0 blue:159.0/255.0 alpha:1.0f] #define SCPinkDark [UIColor colorWithRed:170.0/255.0 green:165.0/255.0 blue:165.0/255.0 alpha:1.0f] #define SCCloudWhite [UIColor colorWithRed:244.0/255.0 green:244.0/255.0 blue:244.0/255.0 alpha:1.0f] #define SCBlack [UIColor colorWithRed:45.0/255.0 green:45.0/255.0 blue:45.0/255.0 alpha:1.0f] #define SCStarYellow [UIColor colorWithRed:252.0/255.0 green:223.0/255.0 blue:101.0/255.0 alpha:1.0f] #define SCTwitterColor [UIColor colorWithRed:0.0/255.0 green:171.0/255.0 blue:243.0/255.0 alpha:1.0] #define SCWeiboColor [UIColor colorWithRed:250.0/255.0 green:0.0/255.0 blue:33.0/255.0 alpha:1.0] #define SCiOSGreenColor [UIColor colorWithRed:98.0/255.0 green:247.0/255.0 blue:77.0/255.0 alpha:1.0] #define SCRandomColor [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1.0f] //范围 struct Range { CGFloat max; CGFloat min; }; typedef struct Range CGRange; CG_INLINE CGRange CGRangeMake(CGFloat max, CGFloat min); CG_INLINE CGRange CGRangeMake(CGFloat max, CGFloat min){ CGRange p; p.max = max; p.min = min; return p; } static const CGRange CGRangeZero = {0,0}; @interface SCColor : NSObject - (UIImage *)imageFromColor:(UIColor *)color; @end ================================================ FILE: SCChart/SCChart/SCColor.m ================================================ // // UUColor.m // UUChart // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCColor.h" @implementation SCColor -(id)init{ if (self = [super init]) { } return self; } -(UIImage *)imageFromColor:(UIColor*)color { CGRect rect = CGRectMake(0, 0, 1, 1); UIGraphicsBeginImageContext(rect.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context,[color CGColor]); CGContextFillRect(context, rect); UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return img; } @end ================================================ FILE: SCChart/SCChart/SCGenericChart.h ================================================ // // PNGenericChart.h // PNChartDemo // // Created by Andi Palo on 26/02/15. // Copyright (c) 2015 kevinzhow. All rights reserved. // #import typedef NS_ENUM(NSUInteger, PNLegendPosition) { PNLegendPositionTop = 0, PNLegendPositionBottom = 1, PNLegendPositionLeft = 2, PNLegendPositionRight = 3 }; typedef NS_ENUM(NSUInteger, PNLegendItemStyle) { PNLegendItemStyleStacked = 0, PNLegendItemStyleSerial = 1 }; @interface SCGenericChart : UIView @property (assign, nonatomic) BOOL hasLegend; @property (assign, nonatomic) PNLegendPosition legendPosition; @property (assign, nonatomic) PNLegendItemStyle legendStyle; @property (assign, nonatomic) UIFont *legendFont; @property (assign, nonatomic) UIColor *legendFontColor; @property (assign, nonatomic) NSUInteger labelRowsInSerialMode; /** * returns the Legend View, or nil if no chart data is present. * The origin of the legend frame is 0,0 but you can set it with setFrame:(CGRect) * * @param mWidth Maximum width of legend. Height will depend on this and font size * * @return UIView of Legend */ - (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth; - (void) setupDefaultValues; @end ================================================ FILE: SCChart/SCChart/SCGenericChart.m ================================================ // // PNGenericChart.m // PNChartDemo // // Created by Andi Palo on 26/02/15. // Copyright (c) 2015 kevinzhow. All rights reserved. // #import "SCGenericChart.h" @interface SCGenericChart () @end @implementation SCGenericChart /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ - (void) setupDefaultValues{ self.hasLegend = YES; self.legendPosition = PNLegendPositionBottom; self.legendStyle = PNLegendItemStyleStacked; self.labelRowsInSerialMode = 1; } /** * to be implemented in subclass */ - (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth{ [self doesNotRecognizeSelector:_cmd]; return nil; } - (void) setLabelRowsInSerialMode:(NSUInteger)num{ if (self.legendStyle == PNLegendItemStyleSerial) { _labelRowsInSerialMode = num; }else{ _labelRowsInSerialMode = 1; } } @end ================================================ FILE: SCChart/SCChart/SCLineChart.h ================================================ // // UULineChart.h // UUChartDemo // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import #import "SCColor.h" #define chartMargin 10 #define xLabelMargin 15 #define yLabelMargin 15 #define UULabelHeight 10 #define UUYLabelwidth 30 #define UUTagLabelwidth 80 @interface SCLineChart : UIView @property (strong, nonatomic) NSArray * xLabels; @property (strong, nonatomic) NSArray * yLabels; @property (strong, nonatomic) NSArray * yValues; @property (nonatomic, strong) NSArray * colors; @property (nonatomic) CGFloat xLabelWidth; @property (nonatomic) CGFloat yValueMin; @property (nonatomic) CGFloat yValueMax; @property (nonatomic, assign) CGRange markRange; @property (nonatomic, assign) CGRange chooseRange; @property (nonatomic, assign) BOOL showRange; @property (nonatomic, retain) NSMutableArray *ShowHorizonLine; @property (nonatomic, retain) NSMutableArray *ShowMaxMinArray; -(void)strokeChart; + (CGSize)sizeOfString:(NSString *)text withWidth:(float)width font:(UIFont *)font; @end ================================================ FILE: SCChart/SCChart/SCLineChart.m ================================================ // // UULineChart.m // UUChartDemo // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCLineChart.h" #import "SCColor.h" #import "SCChartLabel.h" #import "SCTool.h" @implementation SCLineChart - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.clipsToBounds = YES; } return self; } -(void)setYValues:(NSArray *)yValues { _yValues = yValues; [self setYLabels:yValues]; } -(void)setYLabels:(NSArray *)yLabels { CGFloat max = 0; CGFloat min = 1000000000; NSInteger rowCount = 0; // 自动计算每个图表适合的行数 for (NSArray * ary in yLabels) { for (NSString *valueString in ary) { CGFloat value = [valueString floatValue]; if (value > max) { max = value; } if (value < min) { min = value; } } } if (self.showRange) { _yValueMin = min; }else{ _yValueMin = 0; } _yValueMax = max; if (_chooseRange.max!=_chooseRange.min) { // 自定义数值范围 _yValueMax = _chooseRange.max; _yValueMin = _chooseRange.min; } else { // 自动计算数值范围和合适的行数 rowCount = [SCTool rowCountWithValueMax:_yValueMax] == 0 ? 5 : [SCTool rowCountWithValueMax:_yValueMax]; _yValueMax = [SCTool rangeMaxWithValueMax:_yValueMax] == 0 ? 100 : [SCTool rangeMaxWithValueMax:_yValueMax]; _yValueMin = 0; } float level = (_yValueMax-_yValueMin) /rowCount; // 每个区间的差值 CGFloat chartCavanHeight = self.frame.size.height - UULabelHeight*3; CGFloat levelHeight = chartCavanHeight /rowCount; // 每个区间的高度 for (int i=0; i0) { CAShapeLayer *shapeLayer = [CAShapeLayer layer]; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(UUYLabelwidth,UULabelHeight+i*levelHeight)]; [path addLineToPoint:CGPointMake(self.frame.size.width,UULabelHeight+i*levelHeight)]; [path closePath]; shapeLayer.path = path.CGPath; shapeLayer.strokeColor = [[[UIColor blackColor] colorWithAlphaComponent:0.1] CGColor]; shapeLayer.fillColor = [[UIColor whiteColor] CGColor]; shapeLayer.lineWidth = 1; [self.layer addSublayer:shapeLayer]; } } } -(void)setXLabels:(NSArray *)xLabels { _xLabels = xLabels; CGFloat num = 0; if (xLabels.count>=20) { num=20.0; }else if (xLabels.count<=1){ num=1.0; }else{ num = xLabels.count; } _xLabelWidth = (self.frame.size.width - UUYLabelwidth)/num; for (int i=0; i=num){ min = num; min_i = j; } } //划线 CAShapeLayer *_chartLine = [CAShapeLayer layer]; _chartLine.lineCap = kCALineCapRound; _chartLine.lineJoin = kCALineJoinBevel; _chartLine.fillColor = [[UIColor whiteColor] CGColor]; _chartLine.lineWidth = 2.0; _chartLine.strokeEnd = 0.0; [self.layer addSublayer:_chartLine]; UIBezierPath *progressline = [UIBezierPath bezierPath]; CGFloat firstValue = [[childAry objectAtIndex:0] floatValue]; CGFloat xPosition = (UUYLabelwidth + _xLabelWidth/2.0); CGFloat chartCavanHeight = self.frame.size.height - UULabelHeight*3; float grade = ((float)firstValue-_yValueMin) / ((float)_yValueMax-_yValueMin); //第一个点 BOOL isShowMaxAndMinPoint = YES; if (self.ShowMaxMinArray) { if ([self.ShowMaxMinArray[i] intValue]>0) { isShowMaxAndMinPoint = (max_i==0 || min_i==0)?NO:YES; }else{ isShowMaxAndMinPoint = YES; } } [self addPoint:CGPointMake(xPosition, chartCavanHeight - grade * chartCavanHeight+UULabelHeight) index:i isShow:isShowMaxAndMinPoint value:firstValue]; [progressline moveToPoint:CGPointMake(xPosition, chartCavanHeight - grade * chartCavanHeight+UULabelHeight)]; [progressline setLineWidth:2.0]; [progressline setLineCapStyle:kCGLineCapRound]; [progressline setLineJoinStyle:kCGLineJoinRound]; NSInteger index = 0; for (NSString * valueString in childAry) { float grade =([valueString floatValue]-_yValueMin) / ((float)_yValueMax-_yValueMin); if (index != 0) { CGPoint point = CGPointMake(xPosition+index*_xLabelWidth, chartCavanHeight - grade * chartCavanHeight+UULabelHeight); [progressline addLineToPoint:point]; BOOL isShowMaxAndMinPoint = YES; if (self.ShowMaxMinArray) { if ([self.ShowMaxMinArray[i] intValue]>0) { isShowMaxAndMinPoint = (max_i==index || min_i==index)?NO:YES; }else{ isShowMaxAndMinPoint = YES; } } [progressline moveToPoint:point]; [self addPoint:point index:i isShow:isShowMaxAndMinPoint value:[valueString floatValue]]; // [progressline stroke]; } index += 1; } _chartLine.path = progressline.CGPath; if ([[_colors objectAtIndex:i] CGColor]) { _chartLine.strokeColor = [[_colors objectAtIndex:i] CGColor]; }else{ _chartLine.strokeColor = [SCGreen CGColor]; } CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; pathAnimation.duration = childAry.count*0.4; pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; pathAnimation.toValue = [NSNumber numberWithFloat:1.0f]; pathAnimation.autoreverses = NO; [_chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; _chartLine.strokeEnd = 1.0; } } - (void)addPoint:(CGPoint)point index:(NSInteger)index isShow:(BOOL)isHollow value:(CGFloat)value { UIView *view = [[UIView alloc]initWithFrame:CGRectMake(5, 5, 8, 8)]; view.center = point; view.layer.masksToBounds = YES; view.layer.cornerRadius = 4; view.layer.borderWidth = 2; view.layer.borderColor = [[_colors objectAtIndex:index] CGColor]?[[_colors objectAtIndex:index] CGColor]:SCGreen.CGColor; if (isHollow) { view.backgroundColor = [UIColor whiteColor]; }else{ view.backgroundColor = [_colors objectAtIndex:index]?[_colors objectAtIndex:index]:SCGreen; UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(point.x-UUTagLabelwidth/2.0, point.y-UULabelHeight*2, UUTagLabelwidth, UULabelHeight)]; label.font = [UIFont systemFontOfSize:10]; label.textAlignment = NSTextAlignmentCenter; label.textColor = view.backgroundColor; label.text = [NSString stringWithFormat:@"%d",(int)value]; [self addSubview:label]; } [self addSubview:view]; } + (CGSize)sizeOfString:(NSString *)text withWidth:(float)width font:(UIFont *)font { NSInteger ch; CGSize size = CGSizeMake(width, MAXFLOAT); if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) { NSDictionary *tdic = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]; size = [text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:tdic context:nil].size; } else { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" size = [text sizeWithFont:font constrainedToSize:size lineBreakMode:NSLineBreakByCharWrapping]; #pragma clang diagnostic pop } ch = size.height; return size; } @end ================================================ FILE: SCChart/SCChart/SCPieChart.h ================================================ // // PNPieChart.h // PNChartDemo // // Created by Hang Zhang on 14-5-5. // Copyright (c) 2014年 kevinzhow. All rights reserved. // #import #import "SCPieChartDataItem.h" #import "SCGenericChart.h" #import "SCChartDelegate.h" @interface SCPieChart : SCGenericChart - (id)initWithFrame:(CGRect)frame items:(NSArray *)items; @property (nonatomic, readonly) NSArray *items; /** Default is 18-point Avenir Medium. */ @property (nonatomic) UIFont *descriptionTextFont; /** Default is white. */ @property (nonatomic) UIColor *descriptionTextColor; /** Default is black, with an alpha of 0.4. */ @property (nonatomic) UIColor *descriptionTextShadowColor; /** Default is CGSizeMake(0, 1). */ @property (nonatomic) CGSize descriptionTextShadowOffset; /** Default is 1.0. */ @property (nonatomic) NSTimeInterval duration; /** Show only values, this is useful when legend is present */ @property (nonatomic) BOOL showOnlyValues; /** Show absolute values not relative i.e. percentages */ @property (nonatomic) BOOL showAbsoluteValues; @property (nonatomic, weak) id delegate; - (void)updateChartByNumbers:(NSArray *)numbers; - (void)strokeChart; @end ================================================ FILE: SCChart/SCChart/SCPieChart.m ================================================ // // PNPieChart.m // PNChartDemo // // Created by Hang Zhang on 14-5-5. // Copyright (c) 2014年 kevinzhow. All rights reserved. // #import "SCPieChart.h" //needed for the expected label size #import "SCLineChart.h" @interface SCPieChart() @property (nonatomic) NSArray *items; @property (nonatomic) NSArray *endPercentages; @property (nonatomic) CGFloat outerCircleRadius; @property (nonatomic) CGFloat innerCircleRadius; @property (nonatomic) UIView *contentView; @property (nonatomic) CAShapeLayer *pieLayer; @property (nonatomic) NSMutableArray *descriptionLabels; @property (strong, nonatomic) CAShapeLayer *sectorHighlight; - (void)loadDefault; - (UILabel *)descriptionLabelForItemAtIndex:(NSUInteger)index; - (SCPieChartDataItem *)dataItemForIndex:(NSUInteger)index; - (CGFloat)startPercentageForItemAtIndex:(NSUInteger)index; - (CGFloat)endPercentageForItemAtIndex:(NSUInteger)index; - (CGFloat)ratioForItemAtIndex:(NSUInteger)index; - (CAShapeLayer *)newCircleLayerWithRadius:(CGFloat)radius borderWidth:(CGFloat)borderWidth fillColor:(UIColor *)fillColor borderColor:(UIColor *)borderColor startPercentage:(CGFloat)startPercentage endPercentage:(CGFloat)endPercentage; @end @implementation SCPieChart -(id)initWithFrame:(CGRect)frame items:(NSArray *)items{ self = [self initWithFrame:frame]; if(self){ _items = [NSArray arrayWithArray:items]; _outerCircleRadius = CGRectGetWidth(self.bounds) / 2; _innerCircleRadius = CGRectGetWidth(self.bounds) / 6; _descriptionTextColor = [UIColor whiteColor]; _descriptionTextFont = [UIFont fontWithName:@"Avenir-Medium" size:18.0]; _descriptionTextShadowColor = [[UIColor blackColor] colorWithAlphaComponent:0.4]; _descriptionTextShadowOffset = CGSizeMake(0, 1); _duration = 1.0; [super setupDefaultValues]; [self loadDefault]; } return self; } - (void)loadDefault{ __block CGFloat currentTotal = 0; CGFloat total = [[self.items valueForKeyPath:@"@sum.value"] floatValue]; NSMutableArray *endPercentages = [NSMutableArray new]; [_items enumerateObjectsUsingBlock:^(SCPieChartDataItem *item, NSUInteger idx, BOOL *stop) { if (total == 0){ [endPercentages addObject:@(1.0 / _items.count * (idx + 1))]; }else{ currentTotal += item.value; [endPercentages addObject:@(currentTotal / total)]; } }]; self.endPercentages = [endPercentages copy]; [_contentView removeFromSuperview]; _contentView = [[UIView alloc] initWithFrame:self.bounds]; [self addSubview:_contentView]; _descriptionLabels = [NSMutableArray new]; _pieLayer = [CAShapeLayer layer]; [_contentView.layer addSublayer:_pieLayer]; } #pragma mark - - (void)strokeChart{ [self loadDefault]; SCPieChartDataItem *currentItem; for (int i = 0; i < _items.count; i++) { currentItem = [self dataItemForIndex:i]; CGFloat startPercnetage = [self startPercentageForItemAtIndex:i]; CGFloat endPercentage = [self endPercentageForItemAtIndex:i]; CGFloat radius = _innerCircleRadius + (_outerCircleRadius - _innerCircleRadius) / 2; CGFloat borderWidth = _outerCircleRadius - _innerCircleRadius; CAShapeLayer *currentPieLayer = [self newCircleLayerWithRadius:radius borderWidth:borderWidth fillColor:[UIColor clearColor] borderColor:currentItem.color startPercentage:startPercnetage endPercentage:endPercentage]; [_pieLayer addSublayer:currentPieLayer]; } [self maskChart]; for (int i = 0; i < _items.count; i++) { UILabel *descriptionLabel = [self descriptionLabelForItemAtIndex:i]; [_contentView addSubview:descriptionLabel]; [_descriptionLabels addObject:descriptionLabel]; } } - (UILabel *)descriptionLabelForItemAtIndex:(NSUInteger)index{ SCPieChartDataItem *currentDataItem = [self dataItemForIndex:index]; CGFloat distance = _innerCircleRadius + (_outerCircleRadius - _innerCircleRadius) / 2; CGFloat centerPercentage = ([self startPercentageForItemAtIndex:index] + [self endPercentageForItemAtIndex:index])/ 2; CGFloat rad = centerPercentage * 2 * M_PI; UILabel *descriptionLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 80)]; NSString *titleText = currentDataItem.textDescription; NSString *titleValue; if (self.showAbsoluteValues) { titleValue = [NSString stringWithFormat:@"%.0f",currentDataItem.value]; }else{ titleValue = [NSString stringWithFormat:@"%.0f%%",[self ratioForItemAtIndex:index] * 100]; } if(!titleText || self.showOnlyValues){ descriptionLabel.text = titleValue; } else { NSString* str = [titleValue stringByAppendingString:[NSString stringWithFormat:@"\n%@",titleText]]; descriptionLabel.text = str ; } CGPoint center = CGPointMake(_outerCircleRadius + distance * sin(rad), _outerCircleRadius - distance * cos(rad)); descriptionLabel.font = _descriptionTextFont; CGSize labelSize = [descriptionLabel.text sizeWithAttributes:@{NSFontAttributeName:descriptionLabel.font}]; descriptionLabel.frame = CGRectMake(descriptionLabel.frame.origin.x, descriptionLabel.frame.origin.y, descriptionLabel.frame.size.width, labelSize.height); descriptionLabel.numberOfLines = 0; descriptionLabel.textColor = _descriptionTextColor; descriptionLabel.shadowColor = _descriptionTextShadowColor; descriptionLabel.shadowOffset = _descriptionTextShadowOffset; descriptionLabel.textAlignment = NSTextAlignmentCenter; descriptionLabel.center = center; descriptionLabel.alpha = 0; descriptionLabel.backgroundColor = [UIColor clearColor]; return descriptionLabel; } - (SCPieChartDataItem *)dataItemForIndex:(NSUInteger)index{ return self.items[index]; } - (CGFloat)startPercentageForItemAtIndex:(NSUInteger)index{ if(index == 0){ return 0; } return [_endPercentages[index - 1] floatValue]; } - (CGFloat)endPercentageForItemAtIndex:(NSUInteger)index{ return [_endPercentages[index] floatValue]; } - (CGFloat)ratioForItemAtIndex:(NSUInteger)index{ return [self endPercentageForItemAtIndex:index] - [self startPercentageForItemAtIndex:index]; } #pragma mark private methods - (CAShapeLayer *)newCircleLayerWithRadius:(CGFloat)radius borderWidth:(CGFloat)borderWidth fillColor:(UIColor *)fillColor borderColor:(UIColor *)borderColor startPercentage:(CGFloat)startPercentage endPercentage:(CGFloat)endPercentage{ CAShapeLayer *circle = [CAShapeLayer layer]; CGPoint center = CGPointMake(CGRectGetMidX(self.bounds),CGRectGetMidY(self.bounds)); UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:-M_PI_2 endAngle:M_PI_2 * 3 clockwise:YES]; circle.fillColor = fillColor.CGColor; circle.strokeColor = borderColor.CGColor; circle.strokeStart = startPercentage; circle.strokeEnd = endPercentage; circle.lineWidth = borderWidth; circle.path = path.CGPath; return circle; } - (void)maskChart{ CGFloat radius = _innerCircleRadius + (_outerCircleRadius - _innerCircleRadius) / 2; CGFloat borderWidth = _outerCircleRadius - _innerCircleRadius; CAShapeLayer *maskLayer = [self newCircleLayerWithRadius:radius borderWidth:borderWidth fillColor:[UIColor clearColor] borderColor:[UIColor blackColor] startPercentage:0 endPercentage:1]; _pieLayer.mask = maskLayer; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; animation.duration = _duration; animation.fromValue = @0; animation.toValue = @1; animation.delegate = self; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; animation.removedOnCompletion = YES; [maskLayer addAnimation:animation forKey:@"circleAnimation"]; } - (void)createArcAnimationForLayer:(CAShapeLayer *)layer forKey:(NSString *)key fromValue:(NSNumber *)from toValue:(NSNumber *)to delegate:(id)delegate{ CABasicAnimation *arcAnimation = [CABasicAnimation animationWithKeyPath:key]; arcAnimation.fromValue = @0; arcAnimation.toValue = to; arcAnimation.delegate = delegate; arcAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; [layer addAnimation:arcAnimation forKey:key]; [layer setValue:to forKey:key]; } - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ [_descriptionLabels enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [UIView animateWithDuration:0.2 animations:^(){ [obj setAlpha:1]; }]; }]; } - (void)didTouchAt:(CGPoint)touchLocation { CGPoint circleCenter = CGPointMake(_contentView.bounds.size.width/2, _contentView.bounds.size.height/2); CGFloat distanceFromCenter = sqrtf(powf((touchLocation.y - circleCenter.y),2) + powf((touchLocation.x - circleCenter.x),2)); if (distanceFromCenter < _innerCircleRadius) { if ([self.delegate respondsToSelector:@selector(didUnselectPieItem)]) { [self.delegate didUnselectPieItem]; } [self.sectorHighlight removeFromSuperlayer]; return; } CGFloat percentage = [self findPercentageOfAngleInCircle:circleCenter fromPoint:touchLocation]; int index = 0; while (percentage > [self endPercentageForItemAtIndex:index]) { index ++; } if ([self.delegate respondsToSelector:@selector(userClickedOnPieIndexItem:)]) { [self.delegate userClickedOnPieIndexItem:index]; } if (self.sectorHighlight) { [self.sectorHighlight removeFromSuperlayer]; } SCPieChartDataItem *currentItem = [self dataItemForIndex:index]; CGFloat red,green,blue,alpha; UIColor *old = currentItem.color; [old getRed:&red green:&green blue:&blue alpha:&alpha]; alpha /= 2; UIColor *newColor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; CGFloat startPercnetage = [self startPercentageForItemAtIndex:index]; CGFloat endPercentage = [self endPercentageForItemAtIndex:index]; self.sectorHighlight = [self newCircleLayerWithRadius:_outerCircleRadius + 5 borderWidth:10 fillColor:[UIColor clearColor] borderColor:newColor startPercentage:startPercnetage endPercentage:endPercentage]; [_contentView.layer addSublayer:self.sectorHighlight]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { for (UITouch *touch in touches) { CGPoint touchLocation = [touch locationInView:_contentView]; [self didTouchAt:touchLocation]; } } - (CGFloat) findPercentageOfAngleInCircle:(CGPoint)center fromPoint:(CGPoint)reference{ //Find angle of line Passing In Reference And Center CGFloat angleOfLine = atanf((reference.y - center.y) / (reference.x - center.x)); CGFloat percentage = (angleOfLine + M_PI/2)/(2 * M_PI); return (reference.x - center.x) > 0 ? percentage : percentage + .5; } - (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth{ if ([self.items count] < 1) { return nil; } /* This is a small circle that refers to the chart data */ CGFloat legendCircle = 16; CGFloat hSpacing = 0; CGFloat beforeLabel = legendCircle + hSpacing; /* x and y are the coordinates of the starting point of each legend item */ CGFloat x = 0; CGFloat y = 0; /* accumulated width and height */ CGFloat totalWidth = 0; CGFloat totalHeight = 0; NSMutableArray *legendViews = [[NSMutableArray alloc] init]; /* Determine the max width of each legend item */ CGFloat maxLabelWidth; if (self.legendStyle == PNLegendItemStyleStacked) { maxLabelWidth = mWidth - beforeLabel; }else{ maxLabelWidth = MAXFLOAT; } /* this is used when labels wrap text and the line * should be in the middle of the first row */ CGFloat singleRowHeight = [SCLineChart sizeOfString:@"Test" withWidth:MAXFLOAT font:self.legendFont ? self.legendFont : [UIFont systemFontOfSize:12.0f]].height; NSUInteger counter = 0; NSUInteger rowWidth = 0; NSUInteger rowMaxHeight = 0; for (SCPieChartDataItem *pdata in self.items) { /* Expected label size*/ CGSize labelsize = [SCLineChart sizeOfString:pdata.textDescription withWidth:maxLabelWidth font:self.legendFont ? self.legendFont : [UIFont systemFontOfSize:12.0f]]; if ((rowWidth + labelsize.width + beforeLabel > mWidth)&&(self.legendStyle == PNLegendItemStyleSerial)) { rowWidth = 0; x = 0; y += rowMaxHeight; rowMaxHeight = 0; } rowWidth += labelsize.width + beforeLabel; totalWidth = self.legendStyle == PNLegendItemStyleSerial ? fmaxf(rowWidth, totalWidth) : fmaxf(totalWidth, labelsize.width + beforeLabel); // Add inflexion type [legendViews addObject:[self drawInflexion:legendCircle * .6 center:CGPointMake(x + legendCircle / 2, y + singleRowHeight / 2) andColor:pdata.color]]; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x + beforeLabel, y, labelsize.width, labelsize.height)]; label.text = pdata.textDescription; label.textColor = self.legendFontColor ? self.legendFontColor : [UIColor blackColor]; label.font = self.legendFont ? self.legendFont : [UIFont systemFontOfSize:12.0f]; label.lineBreakMode = NSLineBreakByWordWrapping; label.numberOfLines = 0; rowMaxHeight = fmaxf(rowMaxHeight, labelsize.height); x += self.legendStyle == PNLegendItemStyleStacked ? 0 : labelsize.width + beforeLabel; y += self.legendStyle == PNLegendItemStyleStacked ? labelsize.height : 0; totalHeight = self.legendStyle == PNLegendItemStyleSerial ? fmaxf(totalHeight, rowMaxHeight + y) : totalHeight + labelsize.height; [legendViews addObject:label]; counter ++; } UIView *legend = [[UIView alloc] initWithFrame:CGRectMake(0, 0, totalWidth, totalHeight)]; for (UIView* v in legendViews) { [legend addSubview:v]; } return legend; } - (UIImageView*)drawInflexion:(CGFloat)size center:(CGPoint)center andColor:(UIColor*)color { //Make the size a little bigger so it includes also border stroke CGSize aSize = CGSizeMake(size, size); UIGraphicsBeginImageContextWithOptions(aSize, NO, 0.0); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextAddArc(context, size/2, size/ 2, size/2, 0, M_PI*2, YES); //Set some fill color CGContextSetFillColorWithColor(context, color.CGColor); //Finally draw CGContextDrawPath(context, kCGPathFill); //now get the image from the context UIImage *squareImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); //// Translate origin CGFloat originX = center.x - (size) / 2.0; CGFloat originY = center.y - (size) / 2.0; UIImageView *squareImageView = [[UIImageView alloc]initWithImage:squareImage]; [squareImageView setFrame:CGRectMake(originX, originY, size, size)]; return squareImageView; } - (void)updateChartByNumbers:(NSArray *)numbers { for (SCPieChartDataItem *item in self.items) { NSInteger index = [self.items indexOfObject:item]; if (index >= numbers.count) { break; } item.value = [numbers[index] integerValue]; } [self strokeChart]; } @end ================================================ FILE: SCChart/SCChart/SCPieChartDataItem.h ================================================ // // PNPieChartDataItem.h // PNChartDemo // // Created by Hang Zhang on 14-5-5. // Copyright (c) 2014年 kevinzhow. All rights reserved. // #import #import @interface SCPieChartDataItem : NSObject + (instancetype)dataItemWithValue:(CGFloat)value color:(UIColor*)color; + (instancetype)dataItemWithValue:(CGFloat)value color:(UIColor*)color description:(NSString *)description; @property (nonatomic) CGFloat value; @property (nonatomic) UIColor *color; @property (nonatomic) NSString *textDescription; @end ================================================ FILE: SCChart/SCChart/SCPieChartDataItem.m ================================================ // // PNPieChartDataItem.m // PNChartDemo // // Created by Hang Zhang on 14-5-5. // Copyright (c) 2014年 kevinzhow. All rights reserved. // #import "SCPieChartDataItem.h" #import @implementation SCPieChartDataItem + (instancetype)dataItemWithValue:(CGFloat)value color:(UIColor*)color{ SCPieChartDataItem *item = [SCPieChartDataItem new]; item.value = value; item.color = color; return item; } + (instancetype)dataItemWithValue:(CGFloat)value color:(UIColor*)color description:(NSString *)description { SCPieChartDataItem *item = [SCPieChartDataItem dataItemWithValue:value color:color]; item.textDescription = description; return item; } - (void)setValue:(CGFloat)value{ NSAssert(value >= 0, @"value should >= 0"); if (value != _value){ _value = value; } } @end ================================================ FILE: SCChart/SCChart/SCTool.h ================================================ // // UUTool.h // DataCenter // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import @interface SCTool : NSObject /** * 返回图表适合分的行数(4|5|6行) * * @param rangeMax 数组中的最大值 * * @return 图表适合分的行数 */ +(NSInteger)rowCountWithValueMax:(CGFloat)valueMax; /** * 返回适合图表分布的范围内最大值 * * @param rangeMax 数组中的最大值 * * @return 图表适合的范围内最大值 */ +(CGFloat)rangeMaxWithValueMax:(CGFloat)valueMax; @end ================================================ FILE: SCChart/SCChart/SCTool.m ================================================ // // UUTool.m // DataCenter // // Created by 2014-763 on 15/3/12. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCTool.h" @implementation SCTool +(NSInteger)rowCountWithValueMax:(CGFloat)valueMax { NSInteger number1 = 0; NSInteger number2 = 0; NSInteger number3 = 0; NSInteger rowCount = 0; NSString *valueMaxStr = [NSString stringWithFormat:@"%f",valueMax]; for (int i = 0; i < valueMaxStr.length; i++) { NSString *c = [NSString stringWithFormat:@"%c",[valueMaxStr characterAtIndex:i]]; if (![c isEqualToString:@"0"]&&![c isEqualToString:@"."]) { if (number1 == 0) { number1 = [c integerValue]; if (number1 > 2) { break; } } else if (number2 == 0) { number2 = [c integerValue]; if (number2 != 2) { break; } } else if (number3 == 0) { number3 = [c integerValue]; break; } } } if (number1 > 2) { switch (number1) { case 3: case 6: case 7: case 9: rowCount = 4; break; case 4: case 8: rowCount = 5; break; case 5: rowCount = 6; default: break; } } else if (number1 <= 2) { if (number1 == 1) { switch (number2) { case 0: case 1: case 2: { if (number3 < 5) { rowCount = 5; } else if (number3 >= 5) { rowCount = 6; } break; } case 3: case 4: rowCount = 6; break; case 5: case 6: case 7: case 8: case 9: rowCount = 4; break; default: break; } } else if (number1 == 2) { switch (number2) { case 0: case 1: case 2: case 3: case 4: rowCount = 5; break; case 5: case 6: case 7: case 8: case 9: rowCount = 6; break; default: break; } } } return rowCount; } +(CGFloat)rangeMaxWithValueMax:(CGFloat)valueMax { NSInteger number1 = 0; NSInteger number2 = 0; NSInteger number3 = 0; CGFloat rangeMax = 0.0; NSString *valueMaxStr = [NSString stringWithFormat:@"%f",valueMax]; for (int i = 0; i < valueMaxStr.length; i++) { NSString *c = [NSString stringWithFormat:@"%c",[valueMaxStr characterAtIndex:i]]; if (![c isEqualToString:@"0"]&&![c isEqualToString:@"."]) { if (number1 == 0) { number1 = [c integerValue]; if (number1 > 2) { break; } } else if (number2 == 0) { number2 = [c integerValue]; if (number2 != 2) { break; } } else if (number3 == 0) { number3 = [c integerValue]; break; } } } if (number1 > 2) { switch (number1) { case 3: rangeMax = 4; break; case 4: rangeMax = 5; break; case 5: rangeMax = 6; break; case 6: case 7: rangeMax = 8; break; case 8: case 9: rangeMax = 10; break; default: break; } } else if (number1 <= 2) { if (number1 == 1) { switch (number2) { case 0: case 1: case 2: { if (number3 < 5) { rangeMax = 1.25; } else if (number3 >= 5) { rangeMax = 1.5; } break; } case 3: case 4: rangeMax = 1.5; break; case 5: case 6: case 7: case 8: case 9: rangeMax = 2.0; break; default: break; } } else if (number1 == 2) { switch (number2) { case 0: case 1: case 2: case 3: case 4: rangeMax = 2.5; break; case 5: case 6: case 7: case 8: case 9: rangeMax = 3.0; break; default: break; } } } CGFloat n = 1; for (int i = 0; i < valueMaxStr.length; i++) { if (valueMax > 1) { NSString *c = [NSString stringWithFormat:@"%c",[valueMaxStr characterAtIndex:i]]; if (![c isEqualToString:@"."]) { n = n*10; } else { n = n/10; break; } } else { NSString *c = [NSString stringWithFormat:@"%c",[valueMaxStr characterAtIndex:i]]; if ([c isEqualToString:@"0"]) { n = n/10; } else if (![c isEqualToString:@"."]){ break; } } } return rangeMax*n; } @end ================================================ FILE: SCChart/SCChart/UICountingLabel.h ================================================ #import #import typedef enum { UILabelCountingMethodEaseInOut, UILabelCountingMethodEaseIn, UILabelCountingMethodEaseOut, UILabelCountingMethodLinear } UILabelCountingMethod; typedef NSString* (^UICountingLabelFormatBlock)(float value); typedef NSAttributedString* (^UICountingLabelAttributedFormatBlock)(float value); @interface UICountingLabel : UILabel @property (nonatomic, strong) NSString *format; @property (nonatomic, assign) UILabelCountingMethod method; @property (nonatomic, assign) NSTimeInterval animationDuration; @property (nonatomic, copy) UICountingLabelFormatBlock formatBlock; @property (nonatomic, copy) UICountingLabelAttributedFormatBlock attributedFormatBlock; @property (nonatomic, copy) void (^completionBlock)(); -(void)countFrom:(float)startValue to:(float)endValue; -(void)countFrom:(float)startValue to:(float)endValue withDuration:(NSTimeInterval)duration; -(void)countFromCurrentValueTo:(float)endValue; -(void)countFromCurrentValueTo:(float)endValue withDuration:(NSTimeInterval)duration; -(void)countFromZeroTo:(float)endValue; -(void)countFromZeroTo:(float)endValue withDuration:(NSTimeInterval)duration; - (CGFloat)currentValue; @end ================================================ FILE: SCChart/SCChart/UICountingLabel.m ================================================ #import "UICountingLabel.h" #if !__has_feature(objc_arc) #error UICountingLabel is ARC only. Either turn on ARC for the project or use -fobjc-arc flag #endif #pragma mark - UILabelCounter // This whole class & subclasses are private to UICountingLabel, which is why they are declared here in the .m file @interface UILabelCounter : NSObject -(float)update:(float)t; @property float rate; @end @interface UILabelCounterLinear : UILabelCounter @end @interface UILabelCounterEaseIn : UILabelCounter @end @interface UILabelCounterEaseOut : UILabelCounter @end @interface UILabelCounterEaseInOut : UILabelCounter @end @implementation UILabelCounter -(float)update:(float)t{ return 0; } @end @implementation UILabelCounterLinear -(float)update:(float)t { return t; } @end @implementation UILabelCounterEaseIn -(float)update:(float)t { return powf(t, self.rate); } @end @implementation UILabelCounterEaseOut -(float)update:(float)t{ return 1.0-powf((1.0-t), self.rate); } @end @implementation UILabelCounterEaseInOut -(float) update: (float) t { int sign =1; int r = (int) self.rate; if (r % 2 == 0) sign = -1; t *= 2; if (t < 1) return 0.5f * powf (t, self.rate); else return sign*0.5f * (powf (t-2, self.rate) + sign*2); } @end #pragma mark - UICountingLabel @interface UICountingLabel () @property float startingValue; @property float destinationValue; @property NSTimeInterval progress; @property NSTimeInterval lastUpdate; @property NSTimeInterval totalTime; @property float easingRate; @property (nonatomic, weak) NSTimer *timer; @property (nonatomic, strong) UILabelCounter *counter; @end @implementation UICountingLabel -(void)countFrom:(float)value to:(float)endValue { if (self.animationDuration == 0.0f) { self.animationDuration = 2.0f; } [self countFrom:value to:endValue withDuration:self.animationDuration]; } -(void)countFrom:(float)startValue to:(float)endValue withDuration:(NSTimeInterval)duration { self.startingValue = startValue; self.destinationValue = endValue; // remove any (possible) old timers [self.timer invalidate]; self.timer = nil; if (duration == 0.0) { // No animation [self setTextValue:endValue]; [self runCompletionBlock]; return; } self.easingRate = 3.0f; self.progress = 0; self.totalTime = duration; self.lastUpdate = [NSDate timeIntervalSinceReferenceDate]; if(self.format == nil) self.format = @"%f"; switch(self.method) { case UILabelCountingMethodLinear: self.counter = [[UILabelCounterLinear alloc] init]; break; case UILabelCountingMethodEaseIn: self.counter = [[UILabelCounterEaseIn alloc] init]; break; case UILabelCountingMethodEaseOut: self.counter = [[UILabelCounterEaseOut alloc] init]; break; case UILabelCountingMethodEaseInOut: self.counter = [[UILabelCounterEaseInOut alloc] init]; break; } self.counter.rate = 3.0f; NSTimer *timer = [NSTimer timerWithTimeInterval:(1.0f/30.0f) target:self selector:@selector(updateValue:) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:UITrackingRunLoopMode]; self.timer = timer; } - (void)countFromCurrentValueTo:(float)endValue { [self countFrom:[self currentValue] to:endValue]; } - (void)countFromCurrentValueTo:(float)endValue withDuration:(NSTimeInterval)duration { [self countFrom:[self currentValue] to:endValue withDuration:duration]; } - (void)countFromZeroTo:(float)endValue { [self countFrom:0.0f to:endValue]; } - (void)countFromZeroTo:(float)endValue withDuration:(NSTimeInterval)duration { [self countFrom:0.0f to:endValue withDuration:duration]; } - (void)updateValue:(NSTimer *)timer { // update progress NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; self.progress += now - self.lastUpdate; self.lastUpdate = now; if (self.progress >= self.totalTime) { [self.timer invalidate]; self.timer = nil; self.progress = self.totalTime; } [self setTextValue:[self currentValue]]; if (self.progress == self.totalTime) { [self runCompletionBlock]; } } - (void)setTextValue:(float)value { if (self.attributedFormatBlock != nil) { self.attributedText = self.attributedFormatBlock(value); } else if(self.formatBlock != nil) { self.text = self.formatBlock(value); } else { // check if counting with ints - cast to int if([self.format rangeOfString:@"%(.*)d" options:NSRegularExpressionSearch].location != NSNotFound || [self.format rangeOfString:@"%(.*)i"].location != NSNotFound ) { self.text = [NSString stringWithFormat:self.format,(int)value]; } else { self.text = [NSString stringWithFormat:self.format,value]; } } } - (void)setFormat:(NSString *)format { _format = format; // update label with new format [self setTextValue:self.currentValue]; } - (void)runCompletionBlock { if (self.completionBlock) { self.completionBlock(); self.completionBlock = nil; } } - (CGFloat)currentValue { if (self.progress >= self.totalTime) { return self.destinationValue; } CGFloat percent = self.progress / self.totalTime; CGFloat updateVal = [self.counter update:percent]; return self.startingValue + (updateVal * (self.destinationValue - self.startingValue)); } @end ================================================ FILE: SCChart/SCChartCell.h ================================================ // // TableViewCell.h // UUChartView // // Created by shake on 15/1/4. // Copyright (c) 2015年 uyiuyao. All rights reserved. // #import @interface SCChartCell : UITableViewCell - (void)configUI:(NSIndexPath *)indexPath; @end ================================================ FILE: SCChart/SCChartCell.m ================================================ // // TableViewCell.m // UUChartView // // Created by shake on 15/1/4. // Copyright (c) 2015年 uyiuyao. All rights reserved. // #import "SCChartCell.h" #import "SCChart.h" @interface SCChartCell () { NSIndexPath *path; SCChart *chartView; } @end @implementation SCChartCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; [btn setTitle:@"点击刷新数据" forState:UIControlStateNormal]; btn.titleLabel.font = [UIFont systemFontOfSize:12.0];; [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; btn.frame = CGRectMake(0, 0, SCREEN_WIDTH, 27); [btn addTarget:self action:@selector(btnPressed:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:btn]; } return self; } - (void)btnPressed:(id)sender { [chartView strokeChart]; } - (void)configUI:(NSIndexPath *)indexPath { if (chartView) { [chartView removeFromSuperview]; chartView = nil; } path = indexPath; chartView = [[SCChart alloc] initwithSCChartDataFrame:CGRectMake(10, (self.frame.size.height-150)/2, [UIScreen mainScreen].bounds.size.width - 20, 150) withSource:self withStyle:SCChartLineStyle]; [chartView showInView:self.contentView]; } - (NSArray *)getXTitles:(int)num { NSMutableArray *xTitles = [NSMutableArray array]; for (int i=0; i @interface SCCircleCell : UITableViewCell - (void)configUI:(NSIndexPath *)indexPath; @end ================================================ FILE: SCChart/SCCircleCell.m ================================================ // // SCCircleCell.m // SCChart // // Created by 2014-763 on 15/3/24. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCCircleCell.h" #import "SCChart.h" @interface SCCircleCell() { SCCircleChart *chartView; } @end @implementation SCCircleCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; [btn setTitle:@"点击刷新数据" forState:UIControlStateNormal]; btn.titleLabel.font = [UIFont systemFontOfSize:12.0];; [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; btn.frame = CGRectMake(0, 0, SCREEN_WIDTH, 27); [btn addTarget:self action:@selector(btnPressed:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:btn]; } return self; } - (void)btnPressed:(id)sender { CGFloat num = arc4random_uniform(60); [chartView updateChartByCurrent:@(num)]; } - (void)configUI:(NSIndexPath *)indexPath { if (chartView) { [chartView removeFromSuperview]; chartView = nil; } chartView = [[SCCircleChart alloc] initWithFrame:CGRectMake(0, (self.frame.size.height-100)/2, SCREEN_WIDTH, 100.0) total:@100 current:@60 clockwise:YES]; [chartView setStrokeColor:SCBlue]; chartView.chartType = SCChartFormatTypeNone; chartView.format = @"无线端\n%d%%"; [chartView strokeChart]; [self addSubview:chartView]; } @end ================================================ FILE: SCChart/SCPieCell.h ================================================ // // SCPieCell.h // SCChart // // Created by 2014-763 on 15/3/24. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import @interface SCPieCell : UITableViewCell - (void)configUI:(NSIndexPath *)indexPath; @end ================================================ FILE: SCChart/SCPieCell.m ================================================ // // SCPieCell.m // SCChart // // Created by 2014-763 on 15/3/24. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCPieCell.h" #import "SCChart.h" @interface SCPieCell() { SCPieChart *chartView; } @end @implementation SCPieCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; [btn setTitle:@"点击刷新数据" forState:UIControlStateNormal]; btn.titleLabel.font = [UIFont systemFontOfSize:12.0];; [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; btn.frame = CGRectMake(0, 0, SCREEN_WIDTH, 27); [btn addTarget:self action:@selector(btnPressed:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:btn]; } return self; } - (void)btnPressed:(id)sender { NSMutableArray *ary = [NSMutableArray array]; for (NSInteger i = 0; i < 3; i++) { CGFloat num = arc4random_uniform(100); NSString *str = [NSString stringWithFormat:@"%f",num]; [ary addObject:str]; } [chartView updateChartByNumbers:ary]; } - (void)configUI:(NSIndexPath *)indexPath { if (chartView) { [chartView removeFromSuperview]; chartView = nil; } NSArray *items = @[[SCPieChartDataItem dataItemWithValue:10 color:SCRed description:@"A"], [SCPieChartDataItem dataItemWithValue:20 color:SCBlue description:@"B"], [SCPieChartDataItem dataItemWithValue:40 color:SCGreen description:@"C"], ]; chartView = [[SCPieChart alloc] initWithFrame:CGRectMake((SCREEN_WIDTH-150)/2, (self.frame.size.height-150)/2, 150.0, 150.0) items:items]; chartView.descriptionTextColor = [UIColor whiteColor]; chartView.descriptionTextFont = [UIFont fontWithName:@"Avenir-Medium" size:12.0]; [chartView strokeChart]; [self addSubview:chartView]; } @end ================================================ FILE: SCChart/SCViewController.h ================================================ // // SCViewController.h // SCChart // // Created by 2014-763 on 15/3/13. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import @interface SCViewController : UIViewController @end ================================================ FILE: SCChart/SCViewController.m ================================================ // // SCViewController.m // SCChart // // Created by 2014-763 on 15/3/13. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import "SCViewController.h" #import "SCChartCell.h" #import "SCBarCell.h" #import "SCCircleCell.h" #import "SCPieCell.h" @interface SCViewController () @end @implementation SCViewController static NSString *reuseIdentifierChart = @"SCChartCell"; static NSString *reuseIdentifierBar = @"SCBarCell"; static NSString *reuseIdentifierCircle = @"SCCircleCell"; static NSString *reuseIdentifierPie = @"SCPieCell"; - (BOOL)prefersStatusBarHidden { return YES; } - (void)viewDidLoad { [super viewDidLoad]; UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds]; tableView.delegate = self; tableView.dataSource = self; [tableView registerClass:[SCChartCell class] forCellReuseIdentifier:reuseIdentifierChart]; [tableView registerClass:[SCBarCell class] forCellReuseIdentifier:reuseIdentifierBar]; [tableView registerClass:[SCCircleCell class] forCellReuseIdentifier:reuseIdentifierCircle]; [tableView registerClass:[SCPieCell class] forCellReuseIdentifier:reuseIdentifierPie]; tableView.separatorStyle = UITableViewCellSeparatorStyleNone; [self.view addSubview:tableView]; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 4; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { switch (section) { case 0: return 3; break; case 1: return 2; break; case 2: return 1; break; case 3: return 1; break; default: return 0; break; } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { switch (indexPath.section) { case 0: { SCChartCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifierChart forIndexPath:indexPath]; if (!cell) { cell = [[SCChartCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifierChart]; } [cell configUI:indexPath]; cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell; } break; case 1: { SCBarCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifierBar forIndexPath:indexPath]; if (!cell) { cell = [[SCBarCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifierBar]; } [cell configUI:indexPath]; cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell; } break; case 2: { SCChartCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifierCircle forIndexPath:indexPath]; if (!cell) { cell = [[SCChartCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifierCircle]; } [cell configUI:indexPath]; cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell; } break; case 3: { SCPieCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifierPie forIndexPath:indexPath]; if (!cell) { cell = [[SCPieCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifierPie]; } [cell configUI:indexPath]; cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell; } break; default: break; } return nil; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 200; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { CGRect frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width , 30); UILabel *label = [[UILabel alloc]initWithFrame:frame]; label.font = [UIFont systemFontOfSize:14]; label.backgroundColor = [[UIColor lightGrayColor]colorWithAlphaComponent:0.3]; switch (section) { case 0: label.text = @"折线图"; break; case 1: label.text = @"柱状图"; break; case 2: label.text = @"圆形图"; break; case 3: label.text = @"圆饼图"; break; default: break; } label.textColor = [UIColor colorWithRed:0.257 green:0.650 blue:0.478 alpha:1.000]; label.textAlignment = NSTextAlignmentCenter; return label; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 30; } @end ================================================ FILE: SCChart/main.m ================================================ // // main.m // SCChart // // Created by 2014-763 on 15/3/13. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: SCChart.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 250383A81AB2C9D80034BB22 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383A71AB2C9D80034BB22 /* main.m */; }; 250383AB1AB2C9D80034BB22 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383AA1AB2C9D80034BB22 /* AppDelegate.m */; }; 250383B31AB2C9D80034BB22 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 250383B21AB2C9D80034BB22 /* Images.xcassets */; }; 250383B61AB2C9D80034BB22 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 250383B41AB2C9D80034BB22 /* LaunchScreen.xib */; }; 250383C21AB2C9D80034BB22 /* SCChartTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383C11AB2C9D80034BB22 /* SCChartTests.m */; }; 250383CD1AB2CA300034BB22 /* SCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383CC1AB2CA300034BB22 /* SCViewController.m */; }; 250383F31AB2CAA50034BB22 /* SCBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383E61AB2CAA50034BB22 /* SCBar.m */; }; 250383F41AB2CAA50034BB22 /* SCBarChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383E81AB2CAA50034BB22 /* SCBarChart.m */; }; 250383F51AB2CAA50034BB22 /* SCChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383EA1AB2CAA50034BB22 /* SCChart.m */; }; 250383F61AB2CAA50034BB22 /* SCChartLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383EC1AB2CAA50034BB22 /* SCChartLabel.m */; }; 250383F71AB2CAA50034BB22 /* SCColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383EE1AB2CAA50034BB22 /* SCColor.m */; }; 250383F81AB2CAA50034BB22 /* SCLineChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383F01AB2CAA50034BB22 /* SCLineChart.m */; }; 250383F91AB2CAA50034BB22 /* SCTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383F21AB2CAA50034BB22 /* SCTool.m */; }; 250383FE1AB2CCFB0034BB22 /* SCBarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383FB1AB2CCFB0034BB22 /* SCBarCell.m */; }; 250383FF1AB2CCFB0034BB22 /* SCChartCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 250383FD1AB2CCFB0034BB22 /* SCChartCell.m */; }; 25FA1F3C1AC15F4300F4C43F /* SCCircleChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F3B1AC15F4300F4C43F /* SCCircleChart.m */; }; 25FA1F3F1AC15F4B00F4C43F /* UICountingLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F3E1AC15F4B00F4C43F /* UICountingLabel.m */; }; 25FA1F421AC161BF00F4C43F /* SCCircleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F411AC161BF00F4C43F /* SCCircleCell.m */; }; 25FA1F511AC1708800F4C43F /* SCPieChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F4E1AC1708800F4C43F /* SCPieChart.m */; }; 25FA1F521AC1708800F4C43F /* SCPieChartDataItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F501AC1708800F4C43F /* SCPieChartDataItem.m */; }; 25FA1F551AC170B200F4C43F /* SCPieCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F541AC170B200F4C43F /* SCPieCell.m */; }; 25FA1F581AC1718200F4C43F /* SCGenericChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FA1F571AC1718200F4C43F /* SCGenericChart.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 250383BC1AB2C9D80034BB22 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2503839A1AB2C9D80034BB22 /* Project object */; proxyType = 1; remoteGlobalIDString = 250383A11AB2C9D80034BB22; remoteInfo = SCChart; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 250383A21AB2C9D80034BB22 /* SCChart.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SCChart.app; sourceTree = BUILT_PRODUCTS_DIR; }; 250383A61AB2C9D80034BB22 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 250383A71AB2C9D80034BB22 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 250383A91AB2C9D80034BB22 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 250383AA1AB2C9D80034BB22 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 250383B21AB2C9D80034BB22 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 250383B51AB2C9D80034BB22 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 250383BB1AB2C9D80034BB22 /* SCChartTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SCChartTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 250383C01AB2C9D80034BB22 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 250383C11AB2C9D80034BB22 /* SCChartTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SCChartTests.m; sourceTree = ""; }; 250383CB1AB2CA300034BB22 /* SCViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCViewController.h; sourceTree = ""; }; 250383CC1AB2CA300034BB22 /* SCViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCViewController.m; sourceTree = ""; }; 250383E51AB2CAA50034BB22 /* SCBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCBar.h; sourceTree = ""; }; 250383E61AB2CAA50034BB22 /* SCBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCBar.m; sourceTree = ""; }; 250383E71AB2CAA50034BB22 /* SCBarChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCBarChart.h; sourceTree = ""; }; 250383E81AB2CAA50034BB22 /* SCBarChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCBarChart.m; sourceTree = ""; }; 250383E91AB2CAA50034BB22 /* SCChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCChart.h; sourceTree = ""; }; 250383EA1AB2CAA50034BB22 /* SCChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCChart.m; sourceTree = ""; }; 250383EB1AB2CAA50034BB22 /* SCChartLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCChartLabel.h; sourceTree = ""; }; 250383EC1AB2CAA50034BB22 /* SCChartLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCChartLabel.m; sourceTree = ""; }; 250383ED1AB2CAA50034BB22 /* SCColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCColor.h; sourceTree = ""; }; 250383EE1AB2CAA50034BB22 /* SCColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCColor.m; sourceTree = ""; }; 250383EF1AB2CAA50034BB22 /* SCLineChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCLineChart.h; sourceTree = ""; }; 250383F01AB2CAA50034BB22 /* SCLineChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCLineChart.m; sourceTree = ""; }; 250383F11AB2CAA50034BB22 /* SCTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCTool.h; sourceTree = ""; }; 250383F21AB2CAA50034BB22 /* SCTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCTool.m; sourceTree = ""; }; 250383FA1AB2CCFB0034BB22 /* SCBarCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCBarCell.h; sourceTree = ""; }; 250383FB1AB2CCFB0034BB22 /* SCBarCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCBarCell.m; sourceTree = ""; }; 250383FC1AB2CCFB0034BB22 /* SCChartCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCChartCell.h; sourceTree = ""; }; 250383FD1AB2CCFB0034BB22 /* SCChartCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCChartCell.m; sourceTree = ""; }; 25FA1F3A1AC15F4300F4C43F /* SCCircleChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCCircleChart.h; sourceTree = ""; }; 25FA1F3B1AC15F4300F4C43F /* SCCircleChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCCircleChart.m; sourceTree = ""; }; 25FA1F3D1AC15F4B00F4C43F /* UICountingLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICountingLabel.h; sourceTree = ""; }; 25FA1F3E1AC15F4B00F4C43F /* UICountingLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICountingLabel.m; sourceTree = ""; }; 25FA1F401AC161BF00F4C43F /* SCCircleCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCCircleCell.h; sourceTree = ""; }; 25FA1F411AC161BF00F4C43F /* SCCircleCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCCircleCell.m; sourceTree = ""; }; 25FA1F4D1AC1708800F4C43F /* SCPieChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPieChart.h; sourceTree = ""; }; 25FA1F4E1AC1708800F4C43F /* SCPieChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPieChart.m; sourceTree = ""; }; 25FA1F4F1AC1708800F4C43F /* SCPieChartDataItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPieChartDataItem.h; sourceTree = ""; }; 25FA1F501AC1708800F4C43F /* SCPieChartDataItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPieChartDataItem.m; sourceTree = ""; }; 25FA1F531AC170B200F4C43F /* SCPieCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPieCell.h; sourceTree = ""; }; 25FA1F541AC170B200F4C43F /* SCPieCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPieCell.m; sourceTree = ""; }; 25FA1F561AC1718200F4C43F /* SCGenericChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCGenericChart.h; sourceTree = ""; }; 25FA1F571AC1718200F4C43F /* SCGenericChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCGenericChart.m; sourceTree = ""; }; 25FA1F591AC1718E00F4C43F /* SCChartDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCChartDelegate.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 2503839F1AB2C9D80034BB22 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 250383B81AB2C9D80034BB22 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 250383991AB2C9D80034BB22 = { isa = PBXGroup; children = ( 250383A41AB2C9D80034BB22 /* SCChart */, 250383BE1AB2C9D80034BB22 /* SCChartTests */, 250383A31AB2C9D80034BB22 /* Products */, ); sourceTree = ""; }; 250383A31AB2C9D80034BB22 /* Products */ = { isa = PBXGroup; children = ( 250383A21AB2C9D80034BB22 /* SCChart.app */, 250383BB1AB2C9D80034BB22 /* SCChartTests.xctest */, ); name = Products; sourceTree = ""; }; 250383A41AB2C9D80034BB22 /* SCChart */ = { isa = PBXGroup; children = ( 250383E41AB2CAA50034BB22 /* SCChart */, 250383A91AB2C9D80034BB22 /* AppDelegate.h */, 250383AA1AB2C9D80034BB22 /* AppDelegate.m */, 250383CB1AB2CA300034BB22 /* SCViewController.h */, 250383CC1AB2CA300034BB22 /* SCViewController.m */, 250383FC1AB2CCFB0034BB22 /* SCChartCell.h */, 250383FD1AB2CCFB0034BB22 /* SCChartCell.m */, 250383FA1AB2CCFB0034BB22 /* SCBarCell.h */, 250383FB1AB2CCFB0034BB22 /* SCBarCell.m */, 25FA1F401AC161BF00F4C43F /* SCCircleCell.h */, 25FA1F411AC161BF00F4C43F /* SCCircleCell.m */, 25FA1F531AC170B200F4C43F /* SCPieCell.h */, 25FA1F541AC170B200F4C43F /* SCPieCell.m */, 250383B21AB2C9D80034BB22 /* Images.xcassets */, 250383B41AB2C9D80034BB22 /* LaunchScreen.xib */, 250383A51AB2C9D80034BB22 /* Supporting Files */, ); path = SCChart; sourceTree = ""; }; 250383A51AB2C9D80034BB22 /* Supporting Files */ = { isa = PBXGroup; children = ( 250383A61AB2C9D80034BB22 /* Info.plist */, 250383A71AB2C9D80034BB22 /* main.m */, ); name = "Supporting Files"; sourceTree = ""; }; 250383BE1AB2C9D80034BB22 /* SCChartTests */ = { isa = PBXGroup; children = ( 250383C11AB2C9D80034BB22 /* SCChartTests.m */, 250383BF1AB2C9D80034BB22 /* Supporting Files */, ); path = SCChartTests; sourceTree = ""; }; 250383BF1AB2C9D80034BB22 /* Supporting Files */ = { isa = PBXGroup; children = ( 250383C01AB2C9D80034BB22 /* Info.plist */, ); name = "Supporting Files"; sourceTree = ""; }; 250383E41AB2CAA50034BB22 /* SCChart */ = { isa = PBXGroup; children = ( 250383E91AB2CAA50034BB22 /* SCChart.h */, 250383EA1AB2CAA50034BB22 /* SCChart.m */, 250383EF1AB2CAA50034BB22 /* SCLineChart.h */, 250383F01AB2CAA50034BB22 /* SCLineChart.m */, 250383E71AB2CAA50034BB22 /* SCBarChart.h */, 250383E81AB2CAA50034BB22 /* SCBarChart.m */, 25FA1F3A1AC15F4300F4C43F /* SCCircleChart.h */, 25FA1F3B1AC15F4300F4C43F /* SCCircleChart.m */, 25FA1F4D1AC1708800F4C43F /* SCPieChart.h */, 25FA1F4E1AC1708800F4C43F /* SCPieChart.m */, 250383E51AB2CAA50034BB22 /* SCBar.h */, 250383E61AB2CAA50034BB22 /* SCBar.m */, 250383EB1AB2CAA50034BB22 /* SCChartLabel.h */, 250383EC1AB2CAA50034BB22 /* SCChartLabel.m */, 250383ED1AB2CAA50034BB22 /* SCColor.h */, 250383EE1AB2CAA50034BB22 /* SCColor.m */, 250383F11AB2CAA50034BB22 /* SCTool.h */, 250383F21AB2CAA50034BB22 /* SCTool.m */, 25FA1F3D1AC15F4B00F4C43F /* UICountingLabel.h */, 25FA1F3E1AC15F4B00F4C43F /* UICountingLabel.m */, 25FA1F4F1AC1708800F4C43F /* SCPieChartDataItem.h */, 25FA1F501AC1708800F4C43F /* SCPieChartDataItem.m */, 25FA1F561AC1718200F4C43F /* SCGenericChart.h */, 25FA1F571AC1718200F4C43F /* SCGenericChart.m */, 25FA1F591AC1718E00F4C43F /* SCChartDelegate.h */, ); path = SCChart; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 250383A11AB2C9D80034BB22 /* SCChart */ = { isa = PBXNativeTarget; buildConfigurationList = 250383C51AB2C9D80034BB22 /* Build configuration list for PBXNativeTarget "SCChart" */; buildPhases = ( 2503839E1AB2C9D80034BB22 /* Sources */, 2503839F1AB2C9D80034BB22 /* Frameworks */, 250383A01AB2C9D80034BB22 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = SCChart; productName = SCChart; productReference = 250383A21AB2C9D80034BB22 /* SCChart.app */; productType = "com.apple.product-type.application"; }; 250383BA1AB2C9D80034BB22 /* SCChartTests */ = { isa = PBXNativeTarget; buildConfigurationList = 250383C81AB2C9D80034BB22 /* Build configuration list for PBXNativeTarget "SCChartTests" */; buildPhases = ( 250383B71AB2C9D80034BB22 /* Sources */, 250383B81AB2C9D80034BB22 /* Frameworks */, 250383B91AB2C9D80034BB22 /* Resources */, ); buildRules = ( ); dependencies = ( 250383BD1AB2C9D80034BB22 /* PBXTargetDependency */, ); name = SCChartTests; productName = SCChartTests; productReference = 250383BB1AB2C9D80034BB22 /* SCChartTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 2503839A1AB2C9D80034BB22 /* Project object */ = { isa = PBXProject; attributes = { CLASSPREFIX = SC; LastUpgradeCheck = 0610; ORGANIZATIONNAME = meilishuo; TargetAttributes = { 250383A11AB2C9D80034BB22 = { CreatedOnToolsVersion = 6.1; }; 250383BA1AB2C9D80034BB22 = { CreatedOnToolsVersion = 6.1; TestTargetID = 250383A11AB2C9D80034BB22; }; }; }; buildConfigurationList = 2503839D1AB2C9D80034BB22 /* Build configuration list for PBXProject "SCChart" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 250383991AB2C9D80034BB22; productRefGroup = 250383A31AB2C9D80034BB22 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 250383A11AB2C9D80034BB22 /* SCChart */, 250383BA1AB2C9D80034BB22 /* SCChartTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 250383A01AB2C9D80034BB22 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 250383B61AB2C9D80034BB22 /* LaunchScreen.xib in Resources */, 250383B31AB2C9D80034BB22 /* Images.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 250383B91AB2C9D80034BB22 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 2503839E1AB2C9D80034BB22 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 250383F61AB2CAA50034BB22 /* SCChartLabel.m in Sources */, 250383FF1AB2CCFB0034BB22 /* SCChartCell.m in Sources */, 250383F91AB2CAA50034BB22 /* SCTool.m in Sources */, 25FA1F3F1AC15F4B00F4C43F /* UICountingLabel.m in Sources */, 25FA1F421AC161BF00F4C43F /* SCCircleCell.m in Sources */, 25FA1F511AC1708800F4C43F /* SCPieChart.m in Sources */, 25FA1F521AC1708800F4C43F /* SCPieChartDataItem.m in Sources */, 250383FE1AB2CCFB0034BB22 /* SCBarCell.m in Sources */, 250383F71AB2CAA50034BB22 /* SCColor.m in Sources */, 250383AB1AB2C9D80034BB22 /* AppDelegate.m in Sources */, 250383F41AB2CAA50034BB22 /* SCBarChart.m in Sources */, 250383F31AB2CAA50034BB22 /* SCBar.m in Sources */, 250383F81AB2CAA50034BB22 /* SCLineChart.m in Sources */, 25FA1F3C1AC15F4300F4C43F /* SCCircleChart.m in Sources */, 250383CD1AB2CA300034BB22 /* SCViewController.m in Sources */, 250383F51AB2CAA50034BB22 /* SCChart.m in Sources */, 25FA1F551AC170B200F4C43F /* SCPieCell.m in Sources */, 25FA1F581AC1718200F4C43F /* SCGenericChart.m in Sources */, 250383A81AB2C9D80034BB22 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 250383B71AB2C9D80034BB22 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 250383C21AB2C9D80034BB22 /* SCChartTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 250383BD1AB2C9D80034BB22 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 250383A11AB2C9D80034BB22 /* SCChart */; targetProxy = 250383BC1AB2C9D80034BB22 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ 250383B41AB2C9D80034BB22 /* LaunchScreen.xib */ = { isa = PBXVariantGroup; children = ( 250383B51AB2C9D80034BB22 /* Base */, ); name = LaunchScreen.xib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 250383C31AB2C9D80034BB22 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.1; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; 250383C41AB2C9D80034BB22 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; 250383C61AB2C9D80034BB22 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = SCChart/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 250383C71AB2C9D80034BB22 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = SCChart/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; 250383C91AB2C9D80034BB22 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); INFOPLIST_FILE = SCChartTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SCChart.app/SCChart"; }; name = Debug; }; 250383CA1AB2C9D80034BB22 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); INFOPLIST_FILE = SCChartTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SCChart.app/SCChart"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 2503839D1AB2C9D80034BB22 /* Build configuration list for PBXProject "SCChart" */ = { isa = XCConfigurationList; buildConfigurations = ( 250383C31AB2C9D80034BB22 /* Debug */, 250383C41AB2C9D80034BB22 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 250383C51AB2C9D80034BB22 /* Build configuration list for PBXNativeTarget "SCChart" */ = { isa = XCConfigurationList; buildConfigurations = ( 250383C61AB2C9D80034BB22 /* Debug */, 250383C71AB2C9D80034BB22 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 250383C81AB2C9D80034BB22 /* Build configuration list for PBXNativeTarget "SCChartTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 250383C91AB2C9D80034BB22 /* Debug */, 250383CA1AB2C9D80034BB22 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 2503839A1AB2C9D80034BB22 /* Project object */; } ================================================ FILE: SCChartTests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier com.meilishuo.bizfe.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: SCChartTests/SCChartTests.m ================================================ // // SCChartTests.m // SCChartTests // // Created by 2014-763 on 15/3/13. // Copyright (c) 2015年 meilishuo. All rights reserved. // #import #import @interface SCChartTests : XCTestCase @end @implementation SCChartTests - (void)setUp { [super setUp]; // Put setup code here. This method is called before the invocation of each test method in the class. } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; } - (void)testExample { // This is an example of a functional test case. XCTAssert(YES, @"Pass"); } - (void)testPerformanceExample { // This is an example of a performance test case. [self measureBlock:^{ // Put the code you want to measure the time of here. }]; } @end