// // HYBCircleProgressBar.h // CircleBarProject // // Created by huangyibiao on 14-8-16. // Copyright (c) 2014年 Uni2Uni. All rights reserved. // #import <UIKit/UIKit.h> #import <QuartzCore/QuartzCore.h> /*! * @brief 圆形进度条 * @author huangyibiao */ @interface HYBCircleProgressBar : UIView @property (nonatomic, strong) UILabel *percentLabel; - (id)init; - (id)initWithFrame:(CGRect)frame; /*! * @brief 通过调用此方法来更新百分比 * @param percent 当前要显示的值,如90,表示90% * @param animated 是否添加动画更新 */ - (void)setPercent:(int)percent animated:(BOOL)animated; @end
// // HYBCircleProgressBar.m // CircleBarProject // // Created by huangyibiao on 14-8-16. // Copyright (c) 2014骞� Uni2Uni. All rights reserved. // #import "HYBCircleProgressBar.h" #define toRadians(x) ((x) * M_PI / 180.0) #define toDegrees(x) ((x) * 180.0 / M_PI) #define innerRadius 62.5 #define outerRadius 70.5 @interface HYBPercentLayer : CALayer @property (nonatomic) CGFloat percent; @end @implementation HYBPercentLayer - (void)drawInContext:(CGContextRef)context { [self DrawRight:context]; [self DrawLeft:context]; return; } - (void)DrawRight:(CGContextRef)context { CGPoint center = CGPointMake(self.frame.size.width / (2), self.frame.size.height / (2)); CGFloat delta = -toRadians(360 * self.percent); CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor); CGContextSetLineWidth(context, 1); CGContextSetLineCap(context, kCGLineCapRound); CGContextSetAllowsAntialiasing(context, YES); CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRelativeArc(path, NULL, center.x, center.y, innerRadius, -(M_PI / 2), delta); CGPathAddRelativeArc(path, NULL, center.x, center.y, outerRadius, delta - (M_PI / 2), -delta); CGPathAddLineToPoint(path, NULL, center.x, center.y - innerRadius); CGContextAddPath(context, path); CGContextFillPath(context); CFRelease(path); return; } - (void)DrawLeft:(CGContextRef)context { CGPoint center = CGPointMake(self.frame.size.width / (2), self.frame.size.height / (2)); CGFloat delta = toRadians(360 * (1 - self.percent)); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextSetLineWidth(context, 1); CGContextSetLineCap(context, kCGLineCapRound); CGContextSetAllowsAntialiasing(context, YES); CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRelativeArc(path, NULL, center.x, center.y, innerRadius, -(M_PI / 2), delta); CGPathAddRelativeArc(path, NULL, center.x, center.y, outerRadius, delta - (M_PI / 2), -delta); CGPathAddLineToPoint(path, NULL, center.x, center.y - innerRadius); CGContextAddPath(context, path); CGContextFillPath(context); CFRelease(path); return; } @end @interface HYBCircleProgressBar () { UIImage *_thumbImage; HYBPercentLayer *_percentLayer; CALayer *_thumbLayer; } @end @implementation HYBCircleProgressBar - (id)init { return [self initWithFrame:CGRectZero]; } - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.backgroundColor = [UIColor clearColor]; self.clipsToBounds = NO; self.percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 125, 125)]; [self.percentLabel setFont:[UIFont systemFontOfSize:60]]; [self.percentLabel setTextColor:[UIColor colorWithRed:89 / 255.0 green:89 / 255.0 blue:89 / 255.0 alpha:1.0]]; [self.percentLabel setTextAlignment:NSTextAlignmentCenter]; [self.percentLabel setBackgroundColor:[UIColor clearColor]]; self.percentLabel.adjustsFontSizeToFitWidth = YES; [self addSubview:self.percentLabel]; _thumbLayer = [CALayer layer]; _thumbLayer.contentsScale = [UIScreen mainScreen].scale; _thumbLayer.contents = (id)_thumbImage.CGImage; _thumbLayer.frame = CGRectMake(self.frame.size.width / 2 - _thumbImage.size.width / 2, 0, _thumbImage.size.width, _thumbImage.size.height); _thumbLayer.hidden = YES; _percentLayer = [HYBPercentLayer layer]; _percentLayer.contentsScale = [UIScreen mainScreen].scale; _percentLayer.percent = 0; _percentLayer.frame = self.bounds; _percentLayer.masksToBounds = NO; [_percentLayer setNeedsDisplay]; [self.layer addSublayer:_percentLayer]; [self.layer addSublayer:_thumbLayer]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; CGRect frame = self.frame; int percent = _percentLayer.percent * 100; [self.percentLabel setText:[NSString stringWithFormat:@"%i%%", percent]]; CGRect labelFrame = _percentLabel.frame; labelFrame.origin.x = frame.size.width / 2 - _percentLabel.frame.size.width / 2; labelFrame.origin.y = frame.size.height / 2 - _percentLabel.frame.size.height / 2; _percentLabel.frame = labelFrame; return; } #pragma mark - Touch Events - (void)moveThumbToPosition:(CGFloat)angle { CGRect rect = _thumbLayer.frame; CGPoint center = CGPointMake(self.bounds.size.width / 2.0f, self.bounds.size.height/2.0f); angle -= (M_PI/2); rect.origin.x = center.x + 75 * cosf(angle) - (rect.size.width/2); rect.origin.y = center.y + 75 * sinf(angle) - (rect.size.height/2); [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; _thumbLayer.frame = rect; [CATransaction commit]; return; } #pragma mark - Custom Getters/Setters - (void)setPercent:(int)percent animated:(BOOL)animated { CGFloat floatPercent = percent / 100.0; floatPercent = MIN(1, MAX(0, floatPercent)); _percentLayer.percent = floatPercent; [self setNeedsLayout]; [_percentLayer setNeedsDisplay]; [self moveThumbToPosition:floatPercent * (2 * M_PI) - (M_PI / 2)]; return; } @end