圆形进度条定制

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


你可能感兴趣的:(圆形进度条定制)