//
// 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