IOS 圆形进度条

//// CCProgressView.h// Demo//// Created by leao on 2017/8/7.// Copyright ? 2017年 zaodao. All rights reserved.//#import <UIKit/UIKit.h>typedef NS_ENUM(NSInteger, CCProgressViewStyle) { CCProgressViewStyleCircle, // 圆形进度条 CCProgressViewStyleBar, // 条形进度条 CCProgressViewStyleDefault = CCProgressViewStyleCircle,};@interface CCProgressView : UIView@property(nonatomic, assign, setter=setProgress:) CGFloat progress; // 0.0 ~ 1.0@property(nonatomic, assign) CCProgressViewStyle progressViewStyle; // 进度条style@property(nonatomic, strong) UIColor *trackTintColor; // 进度条背景色@property(nonatomic, strong) UIColor *progressTintColor; // 进度条颜色@property(nonatomic, strong) UIColor *progressFullTintColor; // 进度完成时progressTint的颜色@property(nonatomic, assign) CGFloat lineWidth; // 绘制progress宽度 default: 10@property(nonatomic, assign) CGFloat trackerWidth; // 绘制progress宽度 default: 10// CCProgressViewStyleCircle 有效@property(nonatomic, strong) UIColor *fillColor; // 中心颜色@property(nonatomic, assign) BOOL clockwise; // 是否是顺时针 default: YES@property(nonatomic, assign) CGFloat startAngle; // 进度条开始angle, default: -M_PI/2.0@property (nonatomic, strong) UIButton *centerBtn; // 记录进度的Label@property (nonatomic, strong) UIColor *labelbackgroundColor; // Label的背景色 默认clearColor@property (nonatomic, strong) UIColor *textColor; // Label的字体颜色 默认黑色@property (nonatomic, strong) UIFont *textFont; // Label的字体大小 默认15- (void)setProgress:(CGFloat)progress;- (void)setProgress:(CGFloat)progress animated:(BOOL)animated;@end
//// CCProgressView.m// Demo//// Created by leao on 2017/8/7.// Copyright ? 2017年 zaodao. All rights reserved.//#import "CCProgressView.h"#import <pop/POP.h>#import <objc/runtime.h>#import <ReactiveCocoa/ReactiveCocoa.h>#define kCCProgressFillColor [UIColor clearColor]#define kCCProgressTintColor RGBCOLOR(214, 88, 45)#define kCCTrackTintColor RGBCOLOR(243, 212, 187)#define PROGRESS_WIDTH self.frame.size.width#define PROGRESS_HEIGHT self.frame.size.height#define kAnimTimeInterval 2@interface CCProgressView ()@property(nonatomic, strong) CAShapeLayer *trackLayer;@property(nonatomic, strong) CAShapeLayer *progressLayer;@end@implementation CCProgressView- (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { [self initSubviews]; } return self;}- (instancetype)init{ self = [super init]; if (self) { [self initSubviews]; } return self;}#pragma mark - private- (void)initSubviews{ _progressViewStyle = CCProgressViewStyleDefault; _progressTintColor = kCCProgressTintColor; _trackTintColor = kCCTrackTintColor; _lineWidth = 10; _trackerWidth = 10; _fillColor = kCCProgressFillColor; _clockwise = YES; _startAngle = - M_PI / 2.0; self.backgroundColor = [UIColor clearColor]; self.trackLayer = [CAShapeLayer layer]; self.trackLayer.lineCap = kCALineCapButt; self.trackLayer.lineJoin = kCALineCapButt; self.trackLayer.lineWidth = _lineWidth; self.trackLayer.fillColor = nil; self.trackLayer.strokeColor = _trackTintColor.CGColor; self.trackLayer.frame = self.bounds; [self.layer addSublayer:self.trackLayer]; self.progressLayer = [CAShapeLayer layer]; self.progressLayer.lineCap = kCALineCapButt; self.progressLayer.lineJoin = kCALineCapButt; self.progressLayer.lineWidth = _trackerWidth; self.progressLayer.fillColor = _fillColor.CGColor; self.progressLayer.strokeColor = _progressTintColor.CGColor; self.progressLayer.frame = self.bounds; [self.layer addSublayer:self.progressLayer]; self.progressLayer.strokeEnd = 0.0; [self addSubview:self.centerBtn];}- (void)layoutSubviews{ [super layoutSubviews]; [self updateLayerPath];}#pragma mark - private- (UIButton *)centerBtn{ if(!_centerBtn) { _centerBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, PROGRESS_WIDTH - 14, PROGRESS_HEIGHT - 14)]; _centerBtn.center = CGPointMake(PROGRESS_WIDTH/2, PROGRESS_HEIGHT/2); _centerBtn.titleLabel.textAlignment = NSTextAlignmentCenter; _centerBtn.layer.cornerRadius = _centerBtn.width/2; _centerBtn.backgroundColor = RGBCOLOR(246, 227, 204); _centerBtn.titleLabel.adjustsFontSizeToFitWidth = YES; _centerBtn.userInteractionEnabled = NO; _centerBtn.layer.masksToBounds = YES; } return _centerBtn;}- (void)updateLayerPath{ if (_progressViewStyle == CCProgressViewStyleCircle) { self.trackLayer.frame = self.bounds; self.progressLayer.frame = self.bounds; CGFloat radius = CGRectGetWidth(self.frame) > CGRectGetHeight(self.frame) ? (CGRectGetHeight(self.frame) - _lineWidth) / 2.0 : (CGRectGetWidth(self.frame) - _lineWidth) / 2.0; UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:self.progressLayer.position radius:radius startAngle:_startAngle endAngle:_clockwise ? _startAngle + 2 * M_PI : _startAngle - 2 * M_PI clockwise:_clockwise]; self.trackLayer.path = bezierPath.CGPath; self.progressLayer.path = bezierPath.CGPath; } else { self.trackLayer.frame = CGRectMake(0, (CGRectGetHeight(self.frame) - _lineWidth) / 2.0, CGRectGetWidth(self.frame), _lineWidth); self.progressLayer.frame = self.trackLayer.frame; UIBezierPath *bezierPath = [UIBezierPath bezierPath]; [bezierPath moveToPoint:CGPointMake(0, self.progressLayer.position.y)]; [bezierPath addLineToPoint:CGPointMake(CGRectGetWidth(self.frame), self.progressLayer.position.y)]; self.trackLayer.path = bezierPath.CGPath; self.progressLayer.path = bezierPath.CGPath; }}#pragma mark - setter- (void)setTrackTintColor:(UIColor *)trackTintColor{ _trackTintColor = trackTintColor; self.trackLayer.strokeColor = trackTintColor.CGColor;}- (void)setProgressTintColor:(UIColor *)progressTintColor{ _progressTintColor = progressTintColor; self.progressLayer.strokeColor = progressTintColor.CGColor;}- (void)setProgressFullTintColor:(UIColor *)progressFullTintColor{ _progressFullTintColor = progressFullTintColor; if (self.progressLayer.strokeEnd >= 1.0) { self.progressLayer.strokeEnd = 1.0; self.progressLayer.strokeColor = _progressFullTintColor.CGColor; }}- (void)setLineWidth:(CGFloat)lineWidth{ _lineWidth = lineWidth;// self.trackLayer.lineWidth = lineWidth; self.progressLayer.lineWidth = lineWidth; if (_progressViewStyle != CCProgressViewStyleCircle) { [self updateLayerPath]; }}- (void)setTrackerWidth:(CGFloat)trackerWidth { _trackerWidth = trackerWidth; self.trackLayer.lineWidth = _trackerWidth; if (_progressViewStyle != CCProgressViewStyleCircle) { [self updateLayerPath]; }}#pragma mark - setter (CCProgressViewStyleCircle)- (void)setFillColor:(UIColor *)fillColor{ _fillColor = fillColor; self.progressLayer.fillColor = fillColor.CGColor;}- (void)setClockwise:(BOOL)clockwise{ _clockwise = clockwise; [self updateLayerPath];}- (void)setStartAngle:(CGFloat)startAngle{ _startAngle = startAngle; [self updateLayerPath];}- (void)setProgress:(CGFloat)progress{ [self setProgress:progress animated:NO];}- (void)setProgress:(CGFloat)progress animated:(BOOL)animated{ if (animated) { // 这里的动画可以直接使用CABasicAnimation POPBasicAnimation *basicAnim = [POPBasicAnimation animationWithPropertyNamed:kPOPShapeLayerStrokeEnd]; if (basicAnim) { basicAnim.duration = kAnimTimeInterval; basicAnim.toValue = @(progress); } else { basicAnim = [POPBasicAnimation animationWithPropertyNamed:kPOPShapeLayerStrokeEnd]; basicAnim.fromValue = @(self.progressLayer.strokeEnd); basicAnim.toValue = @(progress); basicAnim.duration = 4 * kAnimTimeInterval; basicAnim.removedOnCompletion = YES; } @weakify(self); basicAnim.completionBlock = ^(POPAnimation *anim, BOOL finished) { @strongify(self); POPPropertyAnimation *basicAnim = (POPPropertyAnimation *)anim; self.progressLayer.strokeEnd = [basicAnim.toValue doubleValue]; if (self.progressLayer.strokeEnd >= 1.0 && _progressFullTintColor) { self.progressLayer.strokeEnd = 1.0; self.progressLayer.strokeColor = _progressFullTintColor.CGColor; } }; [self.progressLayer pop_addAnimation:basicAnim forKey:kPOPShapeLayerStrokeEnd]; } else { self.progressLayer.strokeEnd = progress; if (self.progressLayer.strokeEnd >= 1.0 && _progressFullTintColor) { self.progressLayer.strokeEnd = 1.0; self.progressLayer.strokeColor = _progressFullTintColor.CGColor; } }}@end

 

相关文章