iOS 圓弧進度控件設計

zhyv 8年前發布 | 8K 次閱讀 iOS開發 移動開發

帶動畫漸進效果與顏色漸變的圓弧進度控件設計

今天幫朋友寫了一個小巧的圓弧進度控件,控件十分簡單,主要設計思路采用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</code></pre>

    實現方法如下:

    #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_23 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_23 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)(progress100)]]; } [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)(_oldProgress100); new = (int)(_progress100); 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_23 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-_lineWidth2), sqrt(2)/2(_contentWidth-_lineWidth2))]; _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</code></pre>

 本文由用戶 zhyv 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!