iOS 圆形的进度展示View

iOS 圆形的进度展示View

  • 最近项目里需要做一个显示评分等级的控件 但是是圆形的。在网上找了好多,但是没有一模一样的,就自己仿照网上的那些思路自己实现了一个达到UI要求的进度View出来,闲着没事。分别用swift和oc写了一下。内容是一样的 只是不同语言 如果有需要的 直接拿去用吧。


    3879174-609c169859e8d124.gif
  • 还有一点就是我那个三角形不是按照圆的轨迹移动的 因为我是直接改的frame 不过现在无伤大雅吧。以后他们提出要求了再说。

GitHub地址 点这里
直接上代码:

//
//  TCCircleProgressView.m
//  Demo
//

#import "TCCircleProgressView.h"
@interface TCCircleProgressView()

///进度圆
@property (nonatomic, strong) CAShapeLayer * circleLayer;
///分数
@property (nonatomic, strong) UILabel * scoreLabel;
///评分等级
@property (nonatomic, strong) UILabel * stateLabel;
///圆点数组
@property (nonatomic, strong) NSMutableArray * pointLayerArray;
///三角形指示
@property (nonatomic, strong) CAShapeLayer * triangleLayer;

@property (nonatomic, assign) CGPoint customCenter;
///起点偏离角度 本来是以最右边为0开始顺时针到2PI的 如果startOffsetAngle=-0.5PI 则为从顶端开始 依次类推
@property (nonatomic, assign) CGFloat startOffsetAngle;
///三角形指示箭头的半径
@property (nonatomic, assign) CGFloat trangleRadius;

@end

@implementation TCCircleProgressView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self setUpUI];
    }
    return self;
}

- (void)setUpUI {
    self.backgroundColor = [UIColor colorWithRed:31/255.0 green:172/255.0 blue:205/255.0 alpha:1];
    _startOffsetAngle = -1.25* M_PI;
    //圆的大小
    CGFloat rectWidth = 175;
    CGFloat centerX = self.bounds.size.width/2;
    CGFloat centerY = self.bounds.size.height/2;
    _customCenter = CGPointMake(centerX, centerY);
    CGFloat circleRadius = rectWidth/2.0;
    CGFloat lineWidth = 3;
    

    _scoreLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    _scoreLabel.textColor = [UIColor whiteColor];
    _scoreLabel.font = [UIFont boldSystemFontOfSize:70];
    _scoreLabel.textAlignment = NSTextAlignmentCenter;
    _scoreLabel.text = @"50";
    [self addSubview:_scoreLabel];
    
    _scoreLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_scoreLabel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_scoreLabel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];

    
    UILabel * unitLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    unitLabel.textColor = [UIColor whiteColor];
    unitLabel.text = @"分";
    unitLabel.font = [UIFont systemFontOfSize:16];
    [self addSubview:unitLabel];
    unitLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self addConstraint:[NSLayoutConstraint constraintWithItem:unitLabel attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_scoreLabel attribute:NSLayoutAttributeRight multiplier:1 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:unitLabel attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_scoreLabel attribute:NSLayoutAttributeBottom multiplier:1 constant:-10]];

    
    _stateLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMidX(_scoreLabel.frame), CGRectGetMaxY(_scoreLabel.frame), 20, 20)];
    _stateLabel.textColor = [UIColor whiteColor];
    _stateLabel.text = @"高";
    _stateLabel.font = [UIFont systemFontOfSize:16];
    [self addSubview:_stateLabel];
    
    _stateLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_stateLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_scoreLabel attribute:NSLayoutAttributeBottom multiplier:1 constant:-10]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_stateLabel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_scoreLabel attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];

    
    // 创建弧线路径对象

    UIBezierPath *fullCirclePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:rectWidth/2 startAngle:_startOffsetAngle endAngle:2*M_PI + _startOffsetAngle clockwise:YES];
    fullCirclePath.lineCapStyle  = kCGLineCapRound;
    fullCirclePath.lineJoinStyle = kCGLineCapRound;
    
    //整个圆 底部半透明白圆
    CAShapeLayer * fullCirclelayer = [CAShapeLayer layer];
    fullCirclelayer.lineCap = kCALineCapButt;
    fullCirclelayer.fillColor = [UIColor clearColor].CGColor;
    fullCirclelayer.lineWidth = lineWidth;
    fullCirclelayer.strokeColor = [UIColor colorWithWhite:1 alpha:0.4].CGColor;
    fullCirclelayer.path = fullCirclePath.CGPath;
    [self.layer addSublayer:fullCirclelayer];

    //全白进度展示圆
    CAShapeLayer * progressLayer = [CAShapeLayer layer];
    progressLayer.lineCap = kCALineCapButt;
    progressLayer.fillColor = [UIColor clearColor].CGColor;
    progressLayer.lineWidth = lineWidth+1;
    progressLayer.strokeColor = [UIColor whiteColor].CGColor;
    progressLayer.path = fullCirclePath.CGPath;
    progressLayer.strokeStart = 0;
    progressLayer.strokeEnd = 0.1;
    [self.layer addSublayer:progressLayer];
    self.circleLayer = progressLayer;
    
    _pointLayerArray = [NSMutableArray array];
    //外圈圆点 一般设置为进度的整数倍个数 不然会出现指针和圆点错位的情况 现在进度是只有4等分 0% 25% 50% 75% 100% 所以设为4的倍数 16
    int count = 16;
    for (int i = 0; i2) {
        _scoreLabel.font = [UIFont boldSystemFontOfSize:55];
    }
    
    if (progress == 0) {
        _stateLabel.text = @"无";
    }
    else if (progress <=0.25){
        _stateLabel.text = @"低";
    }
    else if (progress == 0.5){
        _stateLabel.text = @"中";
    }
    else if (progress == 0.75){
        _stateLabel.text = @"高";
    }
    else if (progress == 1){
        _stateLabel.text = @"非常高";
    }
    __weak typeof(self) weakSelf = self;
    __block BOOL bigPoint = NO;
    [_pointLayerArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        CALayer * pointLayer = obj;
        pointLayer.affineTransform = CGAffineTransformMakeScale(1, 1);
        if ((float)idx/weakSelf.pointLayerArray.count<=progress) {
            pointLayer.hidden = NO;
        }
        else {
            if (!bigPoint) {
                if (idx>=1) {
                    //最后一个圆点放大
                    CALayer * bigpointLayer = weakSelf.pointLayerArray[idx-1];
                    bigpointLayer.affineTransform = CGAffineTransformMakeScale(2.0, 2.0);
                }
                bigPoint = YES;
            }
            pointLayer.hidden = YES;
        }
    }];
    
    //三角指示器旋转和改变位置
    CGFloat angle = progress*2*M_PI+_startOffsetAngle;
    _triangleLayer.affineTransform = CGAffineTransformRotate(CGAffineTransformIdentity, angle);
    CGFloat triangleCenterX = _customCenter.x + _trangleRadius*cos(angle);
    CGFloat triangleCenterY = _customCenter.y + _trangleRadius*sin(angle);
    _triangleLayer.position = CGPointMake(triangleCenterX, triangleCenterY);
}
@end

你可能感兴趣的:(iOS 圆形的进度展示View)