带动画渐进效果与颜色渐变的圆弧进度控件设计 原

带动画渐进效果与颜色渐变的圆弧进度控件设计

     今天帮朋友写了一个小巧的圆弧进度控件,控件十分简单,主要设计思路采用CAShapeLayer来创建控件圆弧形状,使用CAGradientLayer来进行颜色渐变的渲染,两者结合来创建出颜色渐变的圆弧进度条控件,关于进度动画采用CoreAnimation动画处理。控件进行了简洁的封装,提供了面向使用的接口,需要的朋友可以自取,Demo地址如下:

http://pan.baidu.com/s/1gfqDbtp

      控件中主要提供了,改变进度条渐变颜色,圆弧进度条宽度,带动画效果的改变进度,改变进度百分比字体颜色等方法。效果是例如如下:

改变字体颜色

改变进度

改变进度条颜色

改变进度条宽度

    控件接口的设计:

#import <UIKit/UIKit.h>
@interface YHBaseCircleView : UIView
//==============下面三个渐变色必须全部设置 否则效果可能与预期不同================//
/**
 *设置圆弧渐变色的起始色
 */
@property(nonatomic,strong)UIColor * minLineColor;
/**
 *设置圆弧渐变色的中间色
 */
@property(nonatomic,strong)UIColor * midLineColor;
/**
 *设置圆弧渐变色的终止色
 */
@property(nonatomic,strong)UIColor * maxLineColor;
/**
 *设置圆弧背景色
 */
@property(nonatomic,strong)UIColor * lineTintColor;
/**
 *设置进度
 */
@property(nonatomic,assign)CGFloat progress;
/**
 *设置线的宽度 max = 20 min = 0.5
 */
@property(nonatomic,assign)CGFloat lineWidth;
/**
 *设置是否显示百分比标签
 */
@property(nonatomic,assign)BOOL showTipLabel;
/**
 *设置百分比标签进度颜色
 */
@property(nonatomic,strong)UIColor * textColor;
/**
 *  @brief 设置进度
 *
 *  @param progress 进度 取值0-1
 *
 *  @param animated 是否显示动画
 *
 */
-(void)setProgress:(CGFloat)progress animated:(BOOL)animated;
@end

实现方法如下:

#import "YHBaseCircleView.h"
@implementation YHBaseCircleView
{
    //进度控件内容尺寸
    float _contentWidth;
    float _contentHeight;
    //形状layer
    CAShapeLayer * _shapeLayer;
    //颜色渐变layer
    CAGradientLayer * _gradLayerR;
    CAGradientLayer * _gradLayerL;
    CALayer * _gradLayer;
    //内容layer
    CAShapeLayer * _contentLayer;
    UILabel * _tipLabel;
    //专门用来更新label
    NSTimer * _timer;
    float _oldProgress;
    //进度新旧进度值
    int old;
    int new;
}

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

-(void)reloadView{
    self.backgroundColor = [UIColor clearColor];
    //取设置的frame的最小长或款作为内容区域
    _contentWidth = _contentHeight = CGRectGetWidth(self.frame)>CGRectGetHeight(self.frame)?CGRectGetHeight(self.frame):CGRectGetWidth(self.frame);
    //创建内容layer
    _contentLayer = [CAShapeLayer layer];
    _contentLayer.bounds = CGRectMake(0, 0, _contentWidth, _contentHeight);
    _contentLayer.position = CGPointMake(_contentWidth/2, _contentHeight/2);
    _contentLayer.backgroundColor = [UIColor clearColor].CGColor;
    //进行边界描绘 默认线宽为4px
    UIBezierPath * pathT = [UIBezierPath bezierPathWithArcCenter:_contentLayer.position radius:_contentWidth/2-2 startAngle:-M_PI_2 endAngle:M_PI_2*3 clockwise:YES];
    _contentLayer.path = pathT.CGPath;
    //默认填充颜色为白色
    _contentLayer.fillColor = [UIColor whiteColor].CGColor;
    _contentLayer.lineWidth = 4;
    _contentLayer.strokeColor = [UIColor grayColor].CGColor;
    [self.layer addSublayer:_contentLayer];
    
    _shapeLayer = [CAShapeLayer layer];
    _shapeLayer.bounds = CGRectMake(0, 0, _contentWidth, _contentHeight);
    _shapeLayer.position = CGPointMake(_contentWidth/2, _contentHeight/2);
    _shapeLayer.backgroundColor = [UIColor clearColor].CGColor;
//    _shapeLayer.lineCap  = kCALineCapRound;
    //进行边界描绘 默认线宽为4px
    UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:_shapeLayer.position radius:_contentWidth/2-2 startAngle:-M_PI_2 endAngle:M_PI_2*3 clockwise:YES];
    _shapeLayer.path = path.CGPath;
    _shapeLayer.fillColor = [UIColor clearColor].CGColor;
    _shapeLayer.lineWidth = 4;
    _shapeLayer.strokeColor = [UIColor redColor].CGColor;
    //默认黄转橙转红的边界线 分别由两个gradLayer进行控制
    _gradLayer = [CALayer layer];
    _gradLayer.bounds = _contentLayer.bounds;
    _gradLayer.position = _contentLayer.position;
    _gradLayer.backgroundColor = [UIColor clearColor].CGColor;
    _gradLayerL = [CAGradientLayer layer];
    _gradLayerL.bounds = CGRectMake(0, 0, _contentWidth/2, _contentHeight);
    _gradLayerL.locations = @[@0.6];
    [_gradLayerL setColors:@[(id)[UIColor redColor].CGColor,(id)[UIColor orangeColor].CGColor]];
    _gradLayerL.position = CGPointMake(_gradLayerL.bounds.size.width/2, _gradLayerL.bounds.size.height/2);
   [_gradLayer addSublayer:_gradLayerL];
    _gradLayerR = [CAGradientLayer layer];
    _gradLayerR.locations = @[@0.6];
    _gradLayerR.bounds = CGRectMake(_contentWidth/2, 0, _contentWidth/2, _contentHeight);
    [_gradLayerR setColors:@[(id)[UIColor yellowColor].CGColor,(id)[UIColor orangeColor].CGColor]];
    _gradLayerR.position = CGPointMake(_gradLayerR.bounds.size.width/2+_contentWidth/2, _gradLayerR.bounds.size.height/2);
    [_gradLayer addSublayer:_gradLayerR];
    [_gradLayer setMask:_shapeLayer];
    [_contentLayer addSublayer:_gradLayer];
    
    
    //setter方法初始化
    _minLineColor = [UIColor yellowColor];
    _midLineColor = [UIColor orangeColor];
    _maxLineColor = [UIColor redColor];
    _lineTintColor = [UIColor grayColor];
    _progress = 1;
    _lineWidth = 4;
    _lineTintColor = [UIColor grayColor];
    _textColor = [UIColor orangeColor];
    _oldProgress = 1;
    //创建tiplabel
    [self creatTipLabel];
    _timer = [NSTimer scheduledTimerWithTimeInterval:1/60.0 target:self selector:@selector(updateLabel) userInfo:nil repeats:YES];
    _timer.fireDate = [NSDate distantFuture];
   
}

-(void)removeFromSuperview{
    _timer.fireDate = [NSDate distantFuture];
    [_timer invalidate];
    _timer =nil;
    [super removeFromSuperview];
}
-(void)updateLabel{
    if (old<new) {
        old++;
        NSMutableAttributedString * attri = [[NSMutableAttributedString alloc]initWithString:[NSString stringWithFormat:@"%d%%",old]];
        [attri addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:22] range:NSMakeRange(0, attri.length-1)];
        [attri addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:15] range:NSMakeRange(attri.length-1, 1)];
        [attri addAttribute:NSForegroundColorAttributeName value:_textColor range:NSMakeRange(0, attri.length)];
        _tipLabel.attributedText = attri;
    }else if (old>new){
        old--;
        NSMutableAttributedString * attri = [[NSMutableAttributedString alloc]initWithString:[NSString stringWithFormat:@"%d%%",old]];
        [attri addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:22] range:NSMakeRange(0, attri.length-1)];
        [attri addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:15] range:NSMakeRange(attri.length-1, 1)];
        [attri addAttribute:NSForegroundColorAttributeName value:_textColor range:NSMakeRange(0, attri.length)];
        _tipLabel.attributedText = attri;
    }else{
        _timer.fireDate = [NSDate distantFuture];
    }
}
-(void)setMinLineColor:(UIColor *)minLineColor{
    _minLineColor = minLineColor;
    [_gradLayerR setColors:@[(id)_minLineColor.CGColor,(id)_midLineColor.CGColor]];
    [_gradLayerL setColors:@[(id)_maxLineColor.CGColor,(id)_midLineColor.CGColor]];
}
-(void)setMidLineColor:(UIColor *)midLineColor{
    _midLineColor = midLineColor;
    [_gradLayerR setColors:@[(id)_minLineColor.CGColor,(id)_midLineColor.CGColor]];
    [_gradLayerL setColors:@[(id)_maxLineColor.CGColor,(id)_midLineColor.CGColor]];
}
-(void)setMaxLineColor:(UIColor *)maxLineColor{
    _maxLineColor = maxLineColor;
    [_gradLayerR setColors:@[(id)_minLineColor.CGColor,(id)_midLineColor.CGColor]];
    [_gradLayerL setColors:@[(id)_maxLineColor.CGColor,(id)_midLineColor.CGColor]];
}
-(void)setTintColor:(UIColor *)tintColor{
    _lineTintColor = tintColor;
    _contentLayer.strokeColor = tintColor.CGColor;
}
-(void)setProgress:(CGFloat)progress{
    _oldProgress = _progress;
    _progress=progress;
    _shapeLayer.strokeStart = 0;
    _shapeLayer.strokeEnd = progress>1?1:progress;
    NSMutableAttributedString * attri ;
    if (progress==1) {
        attri = [[NSMutableAttributedString alloc]initWithString:@"100%"];
    }else{
        attri = [[NSMutableAttributedString alloc]initWithString:[NSString stringWithFormat:@"%2d%%",(int)(progress*100)]];
    }
    [attri addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:22] range:NSMakeRange(0, attri.length-1)];
    [attri addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:15] range:NSMakeRange(attri.length-1, 1)];
    [attri addAttribute:NSForegroundColorAttributeName value:_textColor range:NSMakeRange(0, attri.length)];
    _tipLabel.attributedText = attri;
}

-(void)setProgress:(CGFloat)progress animated:(BOOL)animated{
    _oldProgress = _progress;
    _progress = progress;
    old = (int)(_oldProgress*100);
    new = (int)(_progress*100);
    CABasicAnimation * ani = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    ani.toValue = progress>1?@1:@(progress);
    ani.duration = 0.3;
    ani.delegate=self;
    ani.fillMode=kCAFillModeForwards;
    ani.removedOnCompletion=NO;
    [_shapeLayer addAnimation:ani forKey:nil];
    _timer.fireDate = [NSDate distantPast];
    
}
- (void)dealloc
{
    
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    if (flag) {
        [_shapeLayer removeAllAnimations];
        _shapeLayer.strokeEnd = _progress>1?1:_progress;
    }
}
-(void)setLineWidth:(CGFloat)lineWidth{
    if (lineWidth<0.5) {
        lineWidth=0.5;
    }
    if (lineWidth>20) {
        lineWidth = 20;
    }
    _lineWidth = lineWidth;
    UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:_shapeLayer.position radius:_contentWidth/2-lineWidth/2 startAngle:-M_PI_2 endAngle:M_PI_2*3 clockwise:YES];
    _shapeLayer.path = path.CGPath;
    _shapeLayer.fillColor = [UIColor clearColor].CGColor;
    _shapeLayer.lineWidth = lineWidth;
    _shapeLayer.strokeColor = [UIColor redColor].CGColor;
    [_gradLayer setMask:_shapeLayer];
    UIBezierPath * pathT = [UIBezierPath bezierPathWithArcCenter:_contentLayer.position radius:_contentWidth/2-lineWidth/2 startAngle:-M_PI_2 endAngle:M_PI_2*3 clockwise:YES];
    _contentLayer.path = pathT.CGPath;
    _contentLayer.lineWidth = lineWidth;

}
-(void)setTextColor:(UIColor *)textColor{
    _textColor = textColor;
    NSMutableAttributedString * attr = [[NSMutableAttributedString alloc]initWithAttributedString:_tipLabel.attributedText];
    [attr addAttribute:NSForegroundColorAttributeName value:textColor range:NSMakeRange(0, attr.length)];
    _tipLabel.attributedText = attr;
}
-(void)creatTipLabel{
    _tipLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, sqrt(2)/2*(_contentWidth-_lineWidth*2), sqrt(2)/2*(_contentWidth-_lineWidth*2))];
    _tipLabel.center = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
    _tipLabel.backgroundColor = [UIColor clearColor];
    _tipLabel.textAlignment = NSTextAlignmentCenter;
    NSMutableAttributedString * attri = [[NSMutableAttributedString alloc]initWithString:@"100%"];
    [attri addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:22] range:NSMakeRange(0, 3)];
    [attri addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:15] range:NSMakeRange(3, 1)];
    [attri addAttribute:NSForegroundColorAttributeName value:[UIColor orangeColor] range:NSMakeRange(0, 4)];
    _tipLabel.attributedText = attri;
    [self addSubview:_tipLabel];
}
@end

专注技术,热爱生活,交流技术,也做朋友。 ——珲少

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏谈补锅

Quartz2D复习(三) --- 涂鸦

和上一篇手势解锁不一样,手势解锁只画了一条路径,从触摸开始--》触摸移动--》触摸结束 ,然后路径完成了,渲染出来就是手势解锁了;

12530
来自专栏ios 技术积累

ios 圆形进度条

有很多开源的进度条不用,非要弄这种效果,就不吐槽了,还是想想怎么实现 废话就不多说了 直接上代码

27840
来自专栏我和未来有约会

为UINavigationBar添加自定义背景

@implementation UINavigationBar (UINavigationBarCategory) - (void)drawRect:(CGRe...

20890
来自专栏Alice

上边半透明的效果并且显示的是上一页的内容

项目介绍:首先上边显示的是透明的视图,透明度为0.8 这是一个vc 设置vc的view的背景颜色为clearcolor  上边是一个按钮,设置按钮的透明度为0....

21450
来自专栏谈补锅

Quartz2D复习(四) --- 图层CALayer和动画CAAnimation

1)、在ios中,能看得见摸得着的东西基本上都是UIView, 比如按钮、文本标签、文本输入框、图标等,这些都是UIView

10030
来自专栏WindCoder

Canvas初实现拍照小游戏

由于实现的比较简单,且在部分机型上会出现点小问题,此处仅作为js代码的记录,暂不打算写相关教程。

13420
来自专栏coding...

Objective-C 自定义UISlider滑杆 分段样式效果需求分析代码部分DEMO地址

查看UISlider控件发现这个类是继承自UIControl,那么就自定义一个UIControl来实现UISlider没有的效果。 公开的变量中都是一些通用的...

26030
来自专栏Python疯子

UILabel在开发中的常用功能总结

在项目开发中,我们经常会遇到在这样情形: 1、在一个UILabel 使用不同的颜色或不同的字体来体现字符串 在iOS 6 以后我们可以很轻松的实现这一点,官...

12420
来自专栏hrscy

iOS瀑布流

18240
来自专栏狂码一生

js 获取屏幕各种宽高的方法(浏览器兼容)

屏幕的有效宽高: window.screen.availHeight window.screen.availWidth 网页可见区域宽:document.bod...

579100

扫码关注云+社区

领取腾讯云代金券