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

简介:

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

     今天帮朋友写了一个小巧的圆弧进度控件,控件十分简单,主要设计思路采用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
目录
相关文章
|
Web App开发 编解码 JavaScript
Flutter Web:图片相关及跨域问题
在flutter web上也可以使用Image这个widget来加载显示图片。但是涉及到网络图片的时候就可能会出现问题,现象是不显示图片,控制台报错:
2143 0
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
316 1
|
存储 PHP 对象存储
开源免费的图床源码整理汇总-个人自用图床相册程序推荐
图床,也可以称之为相册,即存放图片的地方。 图床与普通的相册不同,图床上传的图片可以作为外链使用,也可以作为公共图片访问使用。除了支持匿名形式访问外,还支持多用户注册与登录,管理员批量管理审核等,当然高级一点功能就是自动审核、AI识别等。 图床需求不如博客建站程序那么,算是一个小众的需要,所以基本上没有什么大规模的免费图床程序。比较受欢迎的Chevereto,已经宣传转为了付费产品,虽然Github上的Chevereto还可以继续下载使用,但是作者已经铁了心要主推他的Chevereto Pro版,免费版的命运走向何方也未知。 本篇文章就来搜集整理一下开源免费的图床源码,由于很多源码都是个人开发
868 0
|
网络协议 安全 Linux
Deepin系统安装x11vnc远程桌面工具实现无公网ip访问本地桌面
Deepin系统安装x11vnc远程桌面工具实现无公网ip访问本地桌面
724 0
|
物联网 Android开发
Android Ble蓝牙App(六)请求MTU与显示设备信息
Android Ble蓝牙App(六)请求MTU与显示设备信息
714 0
|
Swift iOS开发
UISlider自定义滑动条高度(swift)
UISlider滑动条的高度系统默认给我们设定了,没有办法进行改变。可是,我们的设计又是需要改变这个高度的,怎么办呢?这个时候,我们可以写一个UISlider的子类,重写四个方法就能实现了。
3872 0
|
开发工具 git
idea Git不显示每次提交对应的文件
idea Git不显示每次提交对应的文件
797 0
|
小程序 安全 前端开发
微信小程序自定义导航栏机型适配--底部Tabbar--view高度--底部按钮适配
微信小程序自定义导航栏机型适配--底部Tabbar--view高度--底部按钮适配
2014 0
|
API iOS开发 Perl
iOS UISlider自定义渐变色滑杆
iOS UISlider自定义渐变色滑杆
iOS UISlider自定义渐变色滑杆