先上效果图
好了,上代码
- (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:如果折线图需要多次刷新,最好把这些固定参数在初始化时就赋值好,在drwaRect内新建过多变量在高刷新频率下会影响性能
//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]])];//这里为获取每个点坐标的自定义方法,可忽略
}else{
[graphPath addLineToPoint:CGPointMake([self getViewPointXWithCoordHeight:[_distancPoints[i] doubleValue]], [self getViewPointYWithCoordHeight: [_elevationPoints[i] doubleValue]])];
}
graphPath.lineWidth = 2.0;
[graphPath stroke];
//note:屏幕坐标和drawrect内的Y坐标不一样 一个从屏幕上方到下方递增,一个刚好相反,注意做好坐标转换
//step4:绘制折线下面的白色透明渐变色
CGContextSaveGState(context);//储存当前绘制状态
UIBezierPath *clippingPath = [graphPath copy];//复制折线段
[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];//获取封闭路径为编辑区域
CGContextDrawLinearGradient(context, gradient, CGPointMake(Margin, BottomBorder), CGPointMake(Margin, rect.size.height ),0);//绘制渐变色
CGContextRestoreGState(context);//恢复至储存位置的绘制状态(既编辑区域又返回为整个圆角rect,FillColor和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:绘制坐标系白色横线以及数字标识
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:绘制底部横向数字和单位
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}];
}
整体流程就是如此,这里提供的是思路和方法,具体绘制实现需要读者自己去计算每个点的位置、每条线的位置以及单位数量等