自定义环形进度条

作者: SHChen | 来源:发表于2016-03-17 12:28 被阅读626次

    因为年前看到了关于CAShapeLayer方面的东西,所以想用它来实现在工作当中比较容易出现的进度条。之前一直从事的是关于理财的app,而在这类产品当中就很容易出现进度条来展示项目进度,显然的,系统自带的进度条并不能满足我们的需求。。。

    屏幕快照 2016-03-17 下午12.30.57.png

    完成后的效果如下图所示:(PS:还存在有继续封装的空间)

    主页主页 环形进度条环形进度条 环形进度条+文字环形进度条+文字 弧形进度条弧形进度条 弧形进度条+文字弧形进度条+文字

    主要技术点

    1.这里主要使用了贝塞尔曲线和CAShapeLayer的综合使用
    2.确定曲线的端点样式
    3.确定进度的起始点方向

    以第二个环形并且带有文字描述的为例

    CircleWithTextProgressView.h 文件

    #import <UIKit/UIKit.h>
    
    @interface CircleWithTextProgressView : UIView
    
    @property (nonatomic,assign) CGFloat percent;
    
    @property (nonatomic,assign) CGFloat  lineWidth;
    
    @property (strong, nonatomic) NSTimer *timer;
    @end
    

    .m文件

    //
    //  CircleWithTextProgressView.m
    //  SHProgressView
    //
    //  Created by zxy on 16/3/16.
    //  Copyright © 2016年 Chenshaohua. All rights reserved.
    //
    
    #import "CircleWithTextProgressView.h"
    @interface CircleWithTextProgressView()
    {
        CAShapeLayer *_bottomShapeLayer;
        CAShapeLayer *_upperShapeLayer;
        CGFloat _percent;
        UILabel *_percentLabel;
    }
    @end
    @implementation CircleWithTextProgressView
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        if ((self = [super initWithFrame:frame])) {
            [self drawBottomLayer];
            [self drawUpperLayer];
            [self.layer addSublayer:_bottomShapeLayer ];
            
            [_bottomShapeLayer addSublayer:_upperShapeLayer];
            
            // 文本框
            [self drawTextLabel];
            [self addSubview:_percentLabel];
        }
        return self;
    }
    
    - (UILabel *)drawTextLabel
    {
        _percentLabel               = [[UILabel alloc] init];
        CGFloat centerX             = (CGRectGetMaxX(self.frame) - CGRectGetMinX(self.frame)) / 2;
        CGFloat centerY             = (CGRectGetMaxY(self.frame) - CGRectGetMinY(self.frame)) / 2;
        CGFloat width               = self.frame.size.width / 2;
        CGFloat height              = self.frame.size.height / 2;
        _percentLabel.center        = CGPointMake(centerX, centerY);
        _percentLabel.bounds        = CGRectMake(0, 0, width, height);
    
        _percentLabel.font          = [UIFont boldSystemFontOfSize:40];
        _percentLabel.textAlignment = NSTextAlignmentCenter;
        _percentLabel.textColor     = [UIColor redColor];
        
        if (!_timer) {
            _timer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(percentChange) userInfo:nil repeats:YES];
        }
        return _percentLabel;
    }
    
    - (void)percentChange
    {
        _percentLabel.text = [NSString stringWithFormat:@"%.0f%%",_percent * 100];
    }
    
    
    - (CAShapeLayer *)drawBottomLayer
    {
        _bottomShapeLayer                 = [[CAShapeLayer alloc] init];
        _bottomShapeLayer.frame           = self.bounds;
        CGFloat width                     = self.bounds.size.width;
        
        UIBezierPath *path                = [UIBezierPath bezierPathWithArcCenter:CGPointMake((CGRectGetMaxX(self.frame) - CGRectGetMinX(self.frame)) / 2, (CGRectGetMaxY(self.frame) - CGRectGetMinY(self.frame)) / 2)  radius:width / 2 startAngle:0 endAngle:6.28 clockwise:YES];
        _bottomShapeLayer.path            = path.CGPath;
        
        //    _bottomShapeLayer.lineCap = kCALineCapButt;
        //    _bottomShapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:5],[NSNumber numberWithInt:5], nil];
        
        _bottomShapeLayer.lineCap     = kCALineCapSquare;
    
        _bottomShapeLayer.lineWidth   = 15;
        _bottomShapeLayer.strokeColor = [UIColor blackColor].CGColor;
        _bottomShapeLayer.fillColor   = [UIColor clearColor].CGColor;
        return _bottomShapeLayer;
    }
    
    
    - (CAShapeLayer *)drawUpperLayer
    {
        _upperShapeLayer       = [[CAShapeLayer alloc] init];
        _upperShapeLayer.frame = self.bounds;
        CGFloat width          = self.bounds.size.width;
        
        UIBezierPath *path                = [UIBezierPath bezierPathWithArcCenter:CGPointMake((CGRectGetMaxX(self.frame) - CGRectGetMinX(self.frame)) / 2, (CGRectGetMaxY(self.frame) - CGRectGetMinY(self.frame)) / 2)
                                                                           radius:width/ 2
                                                                       startAngle:-1.57
                                                                         endAngle:4.71
                                                                        clockwise:YES];
        _upperShapeLayer.path        = path.CGPath;
        _upperShapeLayer.strokeStart = 0;
        _upperShapeLayer.strokeEnd   = 0;
        [self performSelector:@selector(shapeChange) withObject:nil afterDelay:0.3];
        _upperShapeLayer.lineWidth   = 15;
        
        //    _upperShapeLayer.lineCap = kCALineCapButt;
        //    _upperShapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:5],[NSNumber numberWithInt:5], nil];
        
        _upperShapeLayer.lineCap     = kCALineCapRound;
    
        _upperShapeLayer.strokeColor = [UIColor redColor].CGColor;
        _upperShapeLayer.fillColor   = [UIColor clearColor].CGColor;
        return _upperShapeLayer;
    }
    
    @synthesize percent = _percent;
    - (CGFloat )percent
    {
        return _percent;
    }
    - (void)setPercent:(CGFloat)percent
    {
        _percent = percent;
    
        if (percent > 1) {
        percent  = 1;
        }else if (percent < 0){
        percent  = 0;
        }
        
    }
    
    - (void)shapeChange
    {
        _upperShapeLayer.strokeEnd = _percent;
    }
    
    @end
    
    

    项目github地址

    希望大家多多指教交流:468080538

    相关文章

      网友评论

        本文标题:自定义环形进度条

        本文链接:https://www.haomeiwen.com/subject/nulclttx.html