先上效果圖
好了命爬,上代碼
- (void)drawRect:(CGRect)rect{ ? ?
//step1.繪制帶圓角底圖
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(10, 10)]; ? ?
[path addClip];
//step2.繪制漸變底色
CGContextRef context = UIGraphicsGetCurrentContext(); ? ?
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGFloat locations[2]={0,1.0};//漸變域
NSMutableArray *colors = [NSMutableArray arrayWithCapacity:2];
[colors addObject:(id)[UIColor colorWithRed:250/255.0 green:233/255.0 blue:222/255.0 alpha:1].CGColor];
?[colors addObject:(id)[UIColor colorWithRed:252/255.0 green:79/255.0 blue:8/255.0 alpha:1].CGColor];
CGGradientRef gradient = CGGradientCreateWithColors(space, (CFArrayRef)colors, locations);
CGPoint startPoint = CGPointZero;
CGPoint endPoint = CGPointMake(0, self.bounds.size.height);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
//tips:如果折線圖需要多次刷新,最好把這些固定參數(shù)在初始化時就賦值好啦鸣,在drwaRect內(nèi)新建過多變量在高刷新頻率下會影響性能
//step3.繪制白色折線段
?[[UIColor whiteColor]setFill];
?[[UIColor whiteColor]setStroke];
for (int i = 0; i < _elevationPoints.count; i++) {
?????if (i == 0) {
? ???????[graphPath moveToPoint:CGPointMake([self getViewPointXWithCoordHeight:????????????????[_distancPoints[i] doubleValue]],[self getViewPointYWithCoordHeight:[_elevationPoints[i] doubleValue]])];//這里為獲取每個點坐標(biāo)的自定義方法颗胡,可忽略
? ? }else{
????????[graphPath addLineToPoint:CGPointMake([self getViewPointXWithCoordHeight:[_distancPoints[i] doubleValue]], [self getViewPointYWithCoordHeight:????????[_elevationPoints[i] doubleValue]])];
????}
graphPath.lineWidth = 2.0; ? ?
?[graphPath stroke];
//note:屏幕坐標(biāo)和drawrect內(nèi)的Y坐標(biāo)不一樣 一個從屏幕上方到下方遞增舶担,一個剛好相反惭婿,注意做好坐標(biāo)轉(zhuǎn)換
//step4:繪制折線下面的白色透明漸變色
CGContextSaveGState(context);//儲存當(dāng)前繪制狀態(tài)
UIBezierPath *clippingPath = [graphPath copy];//復(fù)制折線段
[clippingPath addLineToPoint:CGPointMake([self getViewPointXWithCoordHeight:[_distancPoints[_distancPoints.count -1] doubleValue]],rect.size.height - BottomBorder)];
[clippingPath addLineToPoint:CGPointMake([self getViewPointXWithCoordHeight:[_distancPoints[0] doubleValue]],rect.size.height - BottomBorder)];
[clippingPath closePath]; //將折線段添加兩條垂直線(一條垂直X軸,一條垂直Y軸)并閉合歌憨,形成封閉路徑
[clippingPath addClip];//獲取封閉路徑為編輯區(qū)域
CGContextDrawLinearGradient(context, gradient, CGPointMake(Margin, BottomBorder), CGPointMake(Margin, rect.size.height ),0);//繪制漸變色
CGContextRestoreGState(context);//恢復(fù)至儲存位置的繪制狀態(tài)(既編輯區(qū)域又返回為整個圓角rect着憨,F(xiàn)illColor和StrokeColor返回為白色)
//step5:繪制折點
for (int i = 0; i < _elevationPoints.count; i++) {
? ??double pointY = [self getViewPointYWithCoordHeight:[_elevationPoints[i] doubleValue]] - 2.5;
????double pointX = [self getViewPointXWithCoordHeight:[_distancPoints[i] doubleValue]] - 2.5;
????UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(pointX, pointY, 5, 5)];
? ??[circle fill];
}
//step6:繪制坐標(biāo)系白色橫線以及數(shù)字標(biāo)識
?UIBezierPath *linePath = [UIBezierPath bezierPath];
NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init];
?[style setAlignment:NSTextAlignmentCenter];
for (int i = 0; i < 5; i++) {
????double pointY = [self getViewPointYWithCoordHeight:[_elevationLines[i] integerValue]];
????[linePath moveToPoint:CGPointMake(Margin,pointY)];
????[linePath addLineToPoint:CGPointMake(rect.size.width - Margin, pointY)];
????NSString *height = [NSString stringWithFormat:@"%lu",[_elevationLines[i]integerValue]];
????[height drawInRect:CGRectMake(Margin/2-20, pointY-10, 40, 20) ????withAttributes:@{NSFontAttributeName:[UIFont ????systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor ????whiteColor],NSParagraphStyleAttributeName:style}];
}
[[UIColor colorWithWhite:1.0 alpha:0.8] setStroke];
linePath.lineWidth = 1.0;
[linePath stroke];
//step7:繪制底部橫向數(shù)字和單位
NSString *elevationStr = @"(m)海拔";
[elevationStr drawInRect:CGRectMake(Margin/2-20, TopBorder/2-10, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor whiteColor],NSParagraphStyleAttributeName:style}];
NSString *distanceStr = [NSString stringWithFormat:@"%.02f km",self.totalDistance/1000];
[distanceStr drawInRect:CGRectMake(rect.size.width - Margin - 40, rect.size.height-BottomBorder + 10, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor whiteColor],NSParagraphStyleAttributeName:style}];
NSString *midDistanceStr = [NSString stringWithFormat:@"%.02f",self.totalDistance/2000];
[midDistanceStr drawInRect:CGRectMake(rect.size.width / 2.0 - 40, rect.size.height-BottomBorder + 10, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor whiteColor],NSParagraphStyleAttributeName:style}];
NSString *startDistanceStr = @"0";
?[startDistanceStr drawInRect:CGRectMake(Margin - 40, rect.size.height-BottomBorder+10, 80, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor whiteColor],NSParagraphStyleAttributeName:style}];
}
整體流程就是如此,這里提供的是思路和方法务嫡,具體繪制實現(xiàn)需要讀者自己去計算每個點的位置甲抖、每條線的位置以及單位數(shù)量等