今天做一个健身的项目,客户需要一个圆形的进度条来查看个人的运动记录等,做了一些功课之后贴出代码大家一起分享下
代码比较长,多,在这里我先放上demo下载地址 http://download.csdn.net/detail/a174455171/9517479
新建一个继承UIView类
.h文件
@interface MyProgressView : UIView
@property (strong,nonatomic)UILabel *textLabel;
@property (nonatomic)double progress;
@property (nonatomic)NSInteger showTextUI_APPEARANCE_SELECTOR;
@property (nonatomic)NSInteger roundedHeadUI_APPEARANCE_SELECTOR;
@property (nonatomic)NSInteger showShadowUI_APPEARANCE_SELECTOR;
@property (nonatomic)CGFloat thicknessRatioUI_APPEARANCE_SELECTOR;
/**
* 设置内环和外环时使用
*/
@property (nonatomic,strong) UIColor *innerBackgroundColorUI_APPEARANCE_SELECTOR;
@property (nonatomic,strong) UIColor *outerBackgroundColorUI_APPEARANCE_SELECTOR;
@property (nonatomic,strong) UIFont *fontUI_APPEARANCE_SELECTOR;
/**
* 只有一种颜色时使用
*/
@property (nonatomic,strong) UIColor *progressFillColorUI_APPEARANCE_SELECTOR;
@property (nonatomic,strong) UIColor *progressTopGradientColorUI_APPEARANCE_SELECTOR;
@property (nonatomic,strong) UIColor *progressBottomGradientColorUI_APPEARANCE_SELECTOR;
@property (strong,nonatomic)NSArray *colorArray; //多彩时使用
@property (strong,nonatomic)NSArray *shadeArray; //每个颜色处于的位置
@property (nonatomic,readonly)CGFloat *back;
/**
* 设置多彩圆环
*
* @param colorArray 颜色数组
* @param shadeArray 每个颜色处于的位置
*/
-(void)setColorArray:(NSArray *)colorArray shadeArray:(NSArray *)shadeArray;
.m文件
#import <math.h>
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
@interface MyProgressView ()
@property (nonatomic)UIBezierPath *path;
@property (nonatomic)CAShapeLayer *shapeLayer;
@property (nonatomic)UIBezierPath *path1;
@property (nonatomic)CAShapeLayer *shapeLayer1;
@property (strong,nonatomic)UIImageView *imageView;
@end
@implementation MyProgressView
+ (void)initialize
{
if (self == [MyProgressViewclass])
{
id appearance = [selfappearance];
[appearance setShowText:NO];//用来控制是否显示显示label
[appearance setRoundedHead:YES];//用来控制是否对进度两边进行处理
[appearance setShowShadow:YES];//控制圆环进度条的样式
[appearance setThicknessRatio:0.1f];//圆环进度条的宽度
[appearance setInnerBackgroundColor:nil];
[appearance setOuterBackgroundColor:nil];
// [appearance setProgressFillColor:[UIColor redColor]];//整个进度条颜色
// [appearance setProgressTopGradientColor:[UIColor greenColor]];//进度条前半部分颜色
// [appearance setProgressBottomGradientColor:[UIColor redColor]];//进度条后半部分颜色
[appearance setBackgroundColor:[UIColorclearColor]];
}
}
- (void)drawRect:(CGRect)rect
{
// Calculate position of the circle
CGFloat progressAngle = _progress * 360.0 - 90;
CGPoint center = CGPointMake(rect.size.width /2.0f, rect.size.height /2.0f);
CGFloat radius = MIN(rect.size.width, rect.size.height) /2.0f;
CGRect square;
if (rect.size.width > rect.size.height)
{
square = CGRectMake((rect.size.width - rect.size.height) /2.0, 0.0, rect.size.height, rect.size.height);
}
else
{
square = CGRectMake(0.0, (rect.size.height - rect.size.width) / 2.0, rect.size.width, rect.size.width);
}
//进度条宽度
CGFloat circleWidth = radius * _thicknessRatio;
CGContextRef context =UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
if (_innerBackgroundColor)
{
//内环
// Fill innerCircle with innerBackgroundColor
UIBezierPath *innerCircle = [UIBezierPathbezierPathWithArcCenter:center
radius:radius - circleWidth
startAngle:2*M_PI
endAngle:0.0
clockwise:YES];
[_innerBackgroundColorsetFill];
[innerCircle fill];
}
if (_outerBackgroundColor)
{
//外环
// Fill outerCircle with outerBackgroundColor
UIBezierPath *outerCircle = [UIBezierPathbezierPathWithArcCenter:center
radius:radius
startAngle:0.0
endAngle:2*M_PI
clockwise:NO];
[outerCircle addArcWithCenter:center
radius:radius - circleWidth
startAngle:2*M_PI
endAngle:0.0
clockwise:YES];
[_outerBackgroundColorsetFill];
[outerCircle fill];
}
if (_showShadow)
{
//圆环背景处理
CGFloat locations[5] = {0.0f, 0.33f,0.66f, 1.0f };
// NSArray *gradientColors = @[
// (id)[[UIColor colorWithWhite:0.3 alpha:0.5] CGColor],
// (id)[[UIColor colorWithWhite:0.9 alpha:0.0] CGColor],
// (id)[[UIColor colorWithWhite:0.9 alpha:0.0] CGColor],
// (id)[[UIColor colorWithWhite:0.3 alpha:0.5] CGColor],
// ];
NSArray *gradientColors = @[
(id)[[UIColorcolorWithWhite:0.7alpha:1] CGColor],
(id)[[UIColorcolorWithWhite:0.7alpha:1] CGColor],
(id)[[UIColorcolorWithWhite:0.7alpha:1] CGColor],
(id)[[UIColorcolorWithWhite:0.7alpha:1] CGColor],
];
CGColorSpaceRef rgb =CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColors(rgb, (__bridgeCFArrayRef)gradientColors, locations);
CGContextDrawRadialGradient(context, gradient, center, radius - circleWidth, center, radius,0);
CGGradientRelease(gradient);
CGColorSpaceRelease(rgb);
}
if (_showText)
{
if (!_progress) {
return;
}
if ([selfviewWithTag:5]) {
[_textLabelremoveFromSuperview];
}
//中间显示label
_textLabel = [[UILabelalloc] init];
//字符串处理
NSString *str = [NSStringstringWithFormat:@"%0.2f%%\n收益率",_progress * 100.0];
NSMutableAttributedString *progressStr = [[NSMutableAttributedStringalloc] initWithString:str];
//前6位字符 颜色
[progressStr addAttribute:NSForegroundColorAttributeNamevalue:[UIColorredColor] range:NSMakeRange(0,6)];
//第七位向后的3个字符颜色
[progressStr addAttribute:NSForegroundColorAttributeNamevalue:[UIColorblackColor] range:NSMakeRange(7,3)];
[progressStr addAttribute:NSFontAttributeNamevalue:[UIFontboldSystemFontOfSize:16.0]range:NSMakeRange(0,6)];
[progressStr addAttribute:NSFontAttributeNamevalue:[UIFontsystemFontOfSize:13]range:NSMakeRange(7,3)];
_textLabel.attributedText = progressStr;
_textLabel.numberOfLines =0;
_textLabel.bounds =CGRectMake(0,0, 100, 50);
_textLabel.center =CGPointMake(self.bounds.size.width/2.0,self.bounds.size.height/2.0);
_textLabel.tag =5;
_textLabel.textAlignment =NSTextAlignmentCenter;
[self addSubview:_textLabel];
}
UIBezierPath *path = [UIBezierPathbezierPath];
[path appendPath:[UIBezierPathbezierPathWithArcCenter:center
radius:radius
startAngle:DEGREES_TO_RADIANS(-90)
endAngle:DEGREES_TO_RADIANS(progressAngle)
clockwise:YES]];
if (_roundedHead)
{
//终点处理 也可以给终点放置一些图片等
CGPoint point;
point.x = (cos(DEGREES_TO_RADIANS(progressAngle)) * (radius - circleWidth/2)) + center.x;
point.y = (sin(DEGREES_TO_RADIANS(progressAngle)) * (radius - circleWidth/2)) + center.y;
[path addArcWithCenter:point
radius:circleWidth/2
startAngle:DEGREES_TO_RADIANS(progressAngle)
endAngle:DEGREES_TO_RADIANS(270.0 + progressAngle -90.0)
clockwise:YES];
}
[path addArcWithCenter:center
radius:radius-circleWidth
startAngle:DEGREES_TO_RADIANS(progressAngle)
endAngle:DEGREES_TO_RADIANS(-90)
clockwise:NO];
//起始点添加分割线
// UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(radius, 0, 1, circleWidth)];
// lineView.backgroundColor = [UIColor whiteColor];
// [self addSubview:lineView];
if (_roundedHead)
{
//起始点处理
// CGPoint point;
// point.x = (cos(DEGREES_TO_RADIANS(-90)) * (radius - circleWidth/2)) + center.x;
// point.y = (sin(DEGREES_TO_RADIANS(-90)) * (radius - circleWidth/2)) + center.y;
//
// [path addArcWithCenter:point
// radius:circleWidth/2
// startAngle:DEGREES_TO_RADIANS(90)
// endAngle:DEGREES_TO_RADIANS(-90)
// clockwise:NO];
}
[path closePath];
//进度条颜色处理
if (_progressFillColor)
{
[_progressFillColorsetFill];
[path fill];
}
elseif (_progressTopGradientColor &&_progressBottomGradientColor)
{
[path addClip];
NSArray *backgroundColors = @[
(id)[_progressTopGradientColorCGColor],
(id)[_progressBottomGradientColorCGColor],
];
CGFloat backgroudColorLocations[2] = {0.0f,1.0f};
CGColorSpaceRef rgb =CGColorSpaceCreateDeviceRGB();
CGGradientRef backgroundGradient = CGGradientCreateWithColors(rgb, (__bridgeCFArrayRef)(backgroundColors), backgroudColorLocations);
CGContextDrawLinearGradient(context,
backgroundGradient,
CGPointMake(0.0f, square.origin.y),
CGPointMake(0.0f, square.size.height),
0);
CGGradientRelease(backgroundGradient);
CGColorSpaceRelease(rgb);
}
else
{
[path addClip];
NSMutableArray *backgroundColors = [[NSMutableArrayalloc] init];
for (UIColor *colorin _colorArray)
{
[backgroundColors addObject:(id)[colorCGColor]];
}
CGColorSpaceRef rgb =CGColorSpaceCreateDeviceRGB();
CGGradientRef backgroundGradient = CGGradientCreateWithColors(rgb, (__bridgeCFArrayRef)(backgroundColors), _back);
CGContextDrawLinearGradient(context,
backgroundGradient,
CGPointMake(0.0f, square.origin.y),
CGPointMake(0.0f, square.size.height),
0);
CGGradientRelease(backgroundGradient);
CGColorSpaceRelease(rgb);
}
CGContextRestoreGState(context);
}
#pragma mark - Setter
//设置进度
- (void)setProgress:(double)progress
{
_progress = MIN(1.0,MAX(0.0, progress));
[selfsetNeedsDisplay];
}
#pragma mark - UIAppearance
- (void)setShowText:(NSInteger)showText
{
_showText = showText;
[selfsetNeedsDisplay];
}
- (void)setRoundedHead:(NSInteger)roundedHead
{
_roundedHead = roundedHead;
[selfsetNeedsDisplay];
}
- (void)setShowShadow:(NSInteger)showShadow
{
_showShadow = showShadow;
[selfsetNeedsDisplay];
}
//进度条宽度与半径之比
- (void)setThicknessRatio:(CGFloat)thickness
{
_thicknessRatio = MIN(MAX(0.0f, thickness),1.0f);
[selfsetNeedsDisplay];
}
//内环
- (void)setInnerBackgroundColor:(UIColor *)innerBackgroundColor
{
_innerBackgroundColor = innerBackgroundColor;
[selfsetNeedsDisplay];
}
//外环
- (void)setOuterBackgroundColor:(UIColor *)outerBackgroundColor
{
_outerBackgroundColor = outerBackgroundColor;
[selfsetNeedsDisplay];
}
//进度条颜色
- (void)setProgressFillColor:(UIColor *)progressFillColor
{
_progressFillColor = progressFillColor;
[selfsetNeedsDisplay];
}
//进度条前半部分颜色
- (void)setProgressTopGradientColor:(UIColor *)progressTopGradientColor
{
_progressTopGradientColor = progressTopGradientColor;
[selfsetNeedsDisplay];
}
//进度条后半部分颜色
- (void)setProgressBottomGradientColor:(UIColor *)progressBottomGradientColor
{
_progressBottomGradientColor = progressBottomGradientColor;
[selfsetNeedsDisplay];
}
-(void)setColorArray:(NSArray *)colorArray
{
_colorArray = colorArray;
[selfsetNeedsDisplay];
}
-(void)setShadeArray:(NSArray *)shadeArray
{
_shadeArray = shadeArray;
[selfsetNeedsDisplay];
}
-(void)setColorArray:(NSArray *)colorArray shadeArray:(NSArray *)shadeArray
{
_colorArray = colorArray;
_shadeArray = shadeArray;
_back = (CGFloat *)malloc(shadeArray.count*sizeof(CGFloat));
for (int i=0; i<shadeArray.count; i++)
{
_back[i] = [_shadeArray[i]floatValue];
}
[selfsetNeedsDisplay];
}
其中有时候会碰到一些需要一个小点或者在进度终点做一些处理,代码里面都有说明