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

简介:

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

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

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

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

改变字体颜色

改变进度

改变进度条颜色

改变进度条宽度

    控件接口的设计:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#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

实现方法如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#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
目录
相关文章
|
3月前
|
前端开发
背景滑动,动感加倍:CSS动画对角线效果全解析!
背景滑动,动感加倍:CSS动画对角线效果全解析!
|
5月前
|
前端开发
HTML+CSS练习小项目——百叶窗
HTML+CSS练习小项目——百叶窗
|
4月前
|
前端开发
好的商业模式,一定要做的事情,代码库,Canvas画线之蚂蚁线,代码库,一个方框线条断裂循环往复的效果
好的商业模式,一定要做的事情,代码库,Canvas画线之蚂蚁线,代码库,一个方框线条断裂循环往复的效果
|
6月前
|
索引
消除游戏中图标下落的原理和实现
消除游戏中图标下落的原理和实现
47 1
|
编解码 前端开发 容器
ECharts力导向布局图增加滚动条
ECharts力导向布局图增加滚动条
【项目经验】elementui抽屉(从下到上方向)实现向上拉伸
elementui抽屉二次封装(可以向上拉伸)改变抽屉高度
202 0
Photoshop绘制立体效果的拟物化时钟图标
Photoshop绘制立体效果的拟物化时钟图标
77 0
|
小程序
如何做一个俄罗斯方块6:形状停靠
在处理形状停靠之前,有一点儿东西需要了解,就是已经停靠的方块和正在下落的方块不是一种方块,如图,红色的表示的是已经停靠的方块,绿色的表示下落的绿色方块的作用是展示当前下落的形状,红色方块的作用是标识出哪些位置已经摆放了方块。
117 0
|
前端开发 JavaScript 内存技术
css动画animation绘制向四周扩散的圆圈
css动画animation绘制向四周扩散的圆圈
1417 0
|
编解码 前端开发 UED
每日一学—设置页面文字大小随屏幕大小变化而变化(rem布局)
每日学一点加强技术水平,夯实基础。 阅读这篇文章,一起学习rem布局吧。
397 0
每日一学—设置页面文字大小随屏幕大小变化而变化(rem布局)