项目需要做一个有多个色值的进度条,笨办法是创建多个View,给每个View设置不同颜色,当然还是画图更高级点。本次记录利用UIBezierPath和CAShapeLayer来画一条多颜色的线条。
首先我们要先知道整个线条的所有色值,和当前的结果,也就是偏高。然后创建颜色线条类,调用:
NSString *resutStr = @"偏高"; NSArray *colorArr = @[@{@"title":@"极低", @"color":[UIColor redColor]}, @{@"title":@"较低", @"color":[UIColor orangeColor]}, @{@"title":@"偏低", @"color":[UIColor yellowColor]}, @{@"title":@"正常", @"color":[UIColor greenColor]}, @{@"title":@"偏高", @"color":[UIColor cyanColor]}, @{@"title":@"较高", @"color":[UIColor blueColor]}, @{@"title":@"极高", @"color":[UIColor purpleColor]}]; ColorLineView *lineView = [[ColorLineView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 44) levelArr:colorArr currentLevel:resutStr]; [self.view addSubview:lineView];
ColorLineView.m:
@interface ColorLineView () @property (nonatomic,strong) NSArray *levelArr; @property (nonatomic,copy) NSString *remark; @end @implementation ColorLineView -(instancetype)initWithFrame:(CGRect)frame levelArr:(NSArray *)levelArr currentLevel:(NSString *)remark { if (self = [super initWithFrame:frame]) { _levelArr = levelArr; _remark = remark; [self setupUI]; } return self; } -(void)setupUI { //计算当前等级下标 __block NSInteger index = 0; __block NSInteger normalIndex = 0; [self.levelArr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj[@"title"] isEqualToString:@"正常"]) { normalIndex = idx; } if ([obj[@"title"] isEqualToString:_remark]) { index = idx; } }]; //等级名 CGFloat lineW = self.bounds.size.width-40; UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80, 14)]; titleLabel.center = CGPointMake(20 + lineW/self.levelArr.count*index + lineW/self.levelArr.count/2, 7); [self addSubview:titleLabel]; titleLabel.textAlignment = NSTextAlignmentCenter; titleLabel.textColor = self.levelArr[index][@"color"]; titleLabel.font = [UIFont systemFontOfSize:10]; titleLabel.text = [_remark isEqualToString:@"正常"] ? @" " : _remark; //三角标 UIView *triangleView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(titleLabel.frame)-5, CGRectGetMaxY(titleLabel.frame), 10, 6)]; [self addSubview:triangleView]; [self drawTriangle:triangleView color:self.levelArr[index][@"color"]]; //等级条 UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(20, CGRectGetMaxY(triangleView.frame), lineW, 10)]; lineView.layer.cornerRadius = 5; lineView.layer.masksToBounds = YES; [self addSubview:lineView]; [self setupLineView:lineView colors:self.levelArr]; //正常 UILabel *normalLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(lineView.frame), 30, 14)]; normalLabel.center = CGPointMake(20 + lineW/self.levelArr.count*normalIndex + lineW/self.levelArr.count/2, CGRectGetMaxY(lineView.frame)+7); [self addSubview:normalLabel]; normalLabel.textColor = self.levelArr[normalIndex][@"color"]; normalLabel.textAlignment = NSTextAlignmentCenter; normalLabel.font = [UIFont systemFontOfSize:10]; normalLabel.text = @"正常"; } //画三角标 -(void)drawTriangle:(UIView *)triangleView color:(UIColor *)color { UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(0, 0)]; [path addLineToPoint:CGPointMake(10, 0)]; [path addLineToPoint:CGPointMake(5, 6)]; [path closePath]; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = path.CGPath; shapeLayer.fillColor = color.CGColor; [triangleView.layer addSublayer:shapeLayer]; } //画等级条颜色 -(void)setupLineView:(UIView *)lineView colors:(NSArray *)colorArr { __block float a = 0; [colorArr enumerateObjectsUsingBlock:^(NSDictionary * obj, NSUInteger idx, BOOL * _Nonnull stop) { UIBezierPath *linePath = [UIBezierPath bezierPath]; [linePath moveToPoint:CGPointMake(0, lineView.bounds.size.height/2)]; [linePath addLineToPoint:CGPointMake(lineView.bounds.size.width, lineView.bounds.size.height/2)]; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; //每次动画的持续时间 animation.duration = 0.25; //动画起始位置 animation.fromValue = @(0); //动画结束位置 animation.toValue = @(1); CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = linePath.CGPath; shapeLayer.lineWidth = lineView.bounds.size.height; shapeLayer.fillColor = nil; shapeLayer.strokeColor = [obj[@"color"] CGColor]; //strokeStart defaults to zero and strokeEnd to one. shapeLayer.strokeStart = a; //分成了多少段,每次加多少分之一 shapeLayer.strokeEnd = a + 1.0/colorArr.count; //添加动画 [shapeLayer addAnimation:animation forKey:@"strokeEndAnimation"]; [lineView.layer addSublayer:shapeLayer]; a = shapeLayer.strokeEnd; }]; } @end