最近整理以前写的一些小玩意,发现以前写的一个圆形进度环,觉得代码写的还挺简洁的,在此分享给大家.
控件效果:
#import
@class JWProgressView;
@protocol JWProgressViewDelegate
-(void)progressViewOver:(JWProgressView *)progressView;
@end
@interface JWProgressView : UIView
//进度值0-1.0之间
@property (nonatomic,assign)CGFloat progressValue;
//内部label文字
@property(nonatomic,strong)NSString *contentText;
//value等于1的时候的代理
@property(nonatomic,weak)iddelegate;
@end
#import "JWProgressView.h"
@interface JWProgressView ()
{
CAShapeLayer *backGroundLayer; //背景图层
CAShapeLayer *frontFillLayer; //用来填充的图层
UIBezierPath *backGroundBezierPath; //背景贝赛尔曲线
UIBezierPath *frontFillBezierPath; //用来填充的贝赛尔曲线
UILabel *_contentLabel; //中间的label
}
@end
@implementation JWProgressView
@synthesize progressValue = _progressValue;
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
[self setUp];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
[self setUp];
}
return self;
}
//初始化创建图层
- (void)setUp
{
//创建背景图层
backGroundLayer = [CAShapeLayer layer];
backGroundLayer.fillColor = nil;
//创建填充图层
frontFillLayer = [CAShapeLayer layer];
frontFillLayer.fillColor = nil;
//创建中间label
_contentLabel = [[UILabel alloc]init];
_contentLabel.textAlignment = NSTextAlignmentCenter;
_contentLabel.text = @"120";
_contentLabel.font = [UIFont systemFontOfSize:15];
_contentLabel.backgroundColor = [UIColor clearColor];
[self addSubview:_contentLabel];
[self.layer addSublayer:backGroundLayer];
[self.layer addSublayer:frontFillLayer];
//设置颜色
frontFillLayer.strokeColor = [UIColor colorWithRed:78/255.0 green:194/255.0 blue:0/255.0 alpha:1.0].CGColor;
_contentLabel.textColor = [UIColor colorWithRed:78/255.0 green:194/255.0 blue:0/255.0 alpha:1.0];
backGroundLayer.strokeColor = [UIColor colorWithRed:190/255.0 green:255/255.0 blue:167/255.0 alpha:1.0].CGColor;
}
#pragma mark -子控件约束
-(void)layoutSubviews {
[super layoutSubviews];
CGFloat width = self.bounds.size.width;
_contentLabel.frame = CGRectMake(0, 0, width - 4, 20);
_contentLabel.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
backGroundLayer.frame = self.bounds;
backGroundBezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(width/2.0f, width/2.0f) radius:(CGRectGetWidth(self.bounds)-2.0)/2.f startAngle:0 endAngle:M_PI*2
clockwise:YES];
backGroundLayer.path = backGroundBezierPath.CGPath;
frontFillLayer.frame = self.bounds;
//设置线宽
frontFillLayer.lineWidth = 2.0;
backGroundLayer.lineWidth = 2.0;
}
#pragma mark - 设置label文字和进度的方法
-(void)setContentText:(NSString *)contentText {
if (_progressValue == 1) {
return;
}
if (contentText) {
_contentLabel.text = contentText;
}
}
- (void)setProgressValue:(CGFloat)progressValue
{
progressValue = MAX( MIN(progressValue, 1.0), 0.0);
_progressValue = progressValue;
if (progressValue == 1) {
if ([self.delegate respondsToSelector:@selector(progressViewOver:)]) {
[self.delegate progressViewOver:self];
}
return;
}
CGFloat width = self.bounds.size.width;
frontFillBezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(width/2.0f, width/2.0f) radius:(CGRectGetWidth(self.bounds)-2.0)/2.f startAngle:-0.25*2*M_PI endAngle:(2*M_PI)*progressValue - 0.25*2*M_PI clockwise:YES];
frontFillLayer.path = frontFillBezierPath.CGPath;
}
- (CGFloat)progressValue
{
return _progressValue;
}
@end
因为在项目中只用到一次所以就只是做了一个格式化的控件,使用起来也非常的方便.
#import "ViewController.h"
#import "JWProgressView.h"
@interface ViewController ()
{
JWProgressView *progressView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
progressView = [[JWProgressView alloc]initWithFrame:CGRectMake(100, 100, 87, 85)];
progressView.delegate = self;
[self.view addSubview:progressView];
[NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(changeProgressValue) userInfo:nil repeats:YES];
}
- (void)changeProgressValue
{
progressView.progressValue = ((int)((progressView.progressValue * 100.0f) + 1.01) % 100) / 100.0f;;
progressView.contentText=[NSString stringWithFormat:@"%f",progressView.progressValue];
}
-(void)progressViewOver:(JWProgressView *)progressView {
NSLog(@"value为1");
}
对于这种简单并且不会在项目中用到很多次的控件,我的个人理解是不要在外面暴露太多的属性,这样会给代码看起来很不整洁.要是读者想要不同的颜色以及线宽,可以在控件内部代码中修改,属性都有详细的标注.
希望这篇文章有对你实现圆形进度条有所帮助.