iOS UIBezierPath和CAShapeLayer画一条多颜色的线条

项目需要做一个有多个色值的进度条,笨办法是创建多个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



猜你喜欢

转载自blog.csdn.net/txz_gray/article/details/79658208
今日推荐