项目需要做一个有多个色值的进度条,笨办法是创建多个视图,给每个视图设置不同颜色,当然还是画图更高级点。本次记录利用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 {
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)];
__block float a = 0;
[colorArr enumerateObjectsUsingBlock:^(NSDictionary * obj, NSUInteger idx, BOOL * _Nonnull stop) {
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