前言:
百分比圓環(huán)幾乎是所有項(xiàng)目蛾狗,中都會有的。針對于下面的Demo,我們采取雙圓的形式仪媒,進(jìn)行百分比圓環(huán)的案例分析沉桌,并且封裝后,以方便備用算吩。
案例展示
yuanhuan.gif
在這當(dāng)中留凭,有以下幾個難點(diǎn),需要我們清楚:
- 1.畫圓弧利用的是貝塞爾曲線偎巢,我們必須清楚顯示圓環(huán)和輔助圓環(huán)的起點(diǎn)角度和終點(diǎn)角度蔼夜。
- 2.顯示圓環(huán)和輔助圓環(huán)的起點(diǎn)相同,終點(diǎn)不同
- 3.顯示圓環(huán)和輔助圓環(huán)重合(半徑相同压昼,位置相同)求冷,顯示圓環(huán)的終點(diǎn)小于等于輔助圓環(huán)的終點(diǎn)
必須理解一下三幅圖
第一幅圖
第二幅圖
通過上圖,我們可以這樣想,終點(diǎn)的弧度點(diǎn) - 起點(diǎn)弧度點(diǎn) = 整個圓弧的弧度 巢音,整個圓弧的弧度遵倦,我們可以把它看成0%~100%這樣的百分比,例如:在用20%乘以整個圓弧的弧度這個就說明 官撼,在整個弧度中占有20%是多少梧躺。求出來之后在加上起點(diǎn),就是顯示圓的終點(diǎn)傲绣。
第三幅圖
通過上幅圖掠哥,我們要知道起點(diǎn)和終點(diǎn)是怎么平行在一條線上。
代碼示例
ZYCircle.h
#import <UIKit/UIKit.h>
@interface ZYCircle : UIView
//起點(diǎn) 角度
@property(nonatomic) CGFloat startAngle;
//終點(diǎn) 角度
@property(nonatomic)CGFloat endInnerAngle;
//線寬
@property(nonatomic)CGFloat lineWith;
//百分比數(shù)字
@property (nonatomic)CGFloat percentage;
//基準(zhǔn)圓環(huán)顏色
@property(nonatomic,strong)UIColor *unfillColor;
//顯示圓環(huán)顏色
@property(nonatomic,strong)UIColor *fillColor;
//中心數(shù)據(jù)顯示標(biāo)簽
@property (nonatomic ,strong)UILabel *centerLable;
- (instancetype) initWithFrame:(CGRect)frame;
@end
ZYCircle.m
#import "ZYCircle.h"
#define DEGREES_TO_RADIANS(degrees) ((M_PI * degrees)/ 180)
@interface ZYCircle ()
@property(nonatomic) CGPoint CGPoinCerter;
@property(nonatomic) CGFloat endAngle;
@property(nonatomic) BOOL clockwise;
@end
@implementation ZYCircle
{
CGFloat _radius;
}
-(instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.lineWith = 10.0;
self.fillColor = [UIColor greenColor];
self.unfillColor = [UIColor lightGrayColor];
self.clockwise = YES;
self.backgroundColor = [UIColor clearColor];
self.percentage = 0;
self.startAngle = 180;
self.endAngle = 360;
}
return self;
}
#pragma mark setMethod
/**
* 畫圖函數(shù)
*
* @param rect rect description
*/
-(void)drawRect:(CGRect)rect{
[self initData];
[self drawMiddlecircle];
[self drawOutCCircle];
}
-(void)initData
{
>
//中心標(biāo)簽設(shè)置
CGFloat center =MIN(self.bounds.size.height/2, self.bounds.size.width/2);
self.CGPoinCerter = CGPointMake(center, center);
self.centerLable = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 2*center, 2*center)];
self.centerLable.textAlignment=NSTextAlignmentCenter;
self.centerLable.backgroundColor=[UIColor clearColor];
self.centerLable.adjustsFontSizeToFitWidth = YES;
self.centerLable.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.contentMode = UIViewContentModeRedraw;
[self addSubview: self.centerLable];
//半徑計算
_radius = MIN(self.bounds.size.height/2-self.lineWith/2, self.bounds.size.width/2-self.lineWith/2);
self.centerLable.font = [UIFont systemFontOfSize:_radius/3];
self.centerLable.text = [NSString stringWithFormat:@"%.1lf%%",self.percentage*100];
//起點(diǎn)與終點(diǎn)坐標(biāo)
self.endInnerAngle = DEGREES_TO_RADIANS(self.endInnerAngle);
self.startAngle = DEGREES_TO_RADIANS(self.startAngle);
self.endAngle = self.percentage*(self.endInnerAngle - self.startAngle) + self.startAngle;
//0%標(biāo)簽
UILabel *zeroPercentLable = [[UILabel alloc]init];
zeroPercentLable.text = [NSString stringWithFormat:@"0%%"];
CGFloat zeroPercentLableX =_radius + _radius*cos(self.startAngle);
CGFloat zeroPercentLableY = _radius*sin(self.startAngle)+(self.startAngle>DEGREES_TO_RADIANS(180)?-_radius:_radius);
zeroPercentLable.frame = CGRectMake(zeroPercentLableX, zeroPercentLableY+self.lineWith, 2.1*_radius/7.5 + 15, 25);
zeroPercentLable.textAlignment = NSTextAlignmentCenter;
zeroPercentLable.font = [UIFont boldSystemFontOfSize:_radius/7.5 ];
zeroPercentLable.textColor = [UIColor orangeColor];
[self addSubview:zeroPercentLable];
//100%標(biāo)簽
UILabel *hundredPercentLable = [[UILabel alloc]init];
hundredPercentLable.text = [NSString stringWithFormat:@"100%%"];
CGFloat hundredPercentLableX =_radius + _radius*cos(self.endInnerAngle)-8;
CGFloat hundredPercentLableY = _radius*sin(self.endInnerAngle)+(self.endInnerAngle<DEGREES_TO_RADIANS(180)?-_radius:_radius);
hundredPercentLable.frame = CGRectMake(hundredPercentLableX, hundredPercentLableY+self.lineWith, 2.9*_radius/7.5 + 15, 25);
hundredPercentLable.textAlignment = NSTextAlignmentCenter;
hundredPercentLable.font = [UIFont boldSystemFontOfSize:_radius/7.5 ];
hundredPercentLable.textColor = [UIColor orangeColor];
[self addSubview:hundredPercentLable];
}
#pragma mark - 利用layer的 strokeEnd秃诵、strokeStart和lineWidth 屬性添加CA動畫
- (void)addAnimationOneOnLayer:(CAShapeLayer *)layer duration:(CFTimeInterval)duration
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.fromValue = @(0);
animation.toValue = @(1);
animation.duration = duration;
[layer addAnimation:animation forKey:nil];
}
/**
* 顯示圓環(huán)
*/
-(void )drawOutCCircle{
UIBezierPath *bPath = [UIBezierPath bezierPathWithArcCenter:self.CGPoinCerter radius:_radius startAngle:self.startAngle endAngle:self.endAngle clockwise:self.clockwise];
>
CAShapeLayer *layer = [CAShapeLayer layer];
layer.lineWidth = self.lineWith;
layer.lineCap = kCALineCapRound;
layer.lineJoin = kCALineJoinRound;
layer.strokeColor = self.fillColor.CGColor;
layer.fillColor = nil;
layer.path = bPath.CGPath;
[self.layer addSublayer:layer];
>
[self addAnimationOneOnLayer:layer duration:1.0];
}
/**
* 輔助圓環(huán)
*/
-(void)drawMiddlecircle{
UIBezierPath *cPath = [UIBezierPath bezierPathWithArcCenter:self.CGPoinCerter radius:_radius startAngle:self.startAngle endAngle:self.endInnerAngle clockwise:self.clockwise];
cPath.lineWidth=self.lineWith;
cPath.lineCapStyle = kCGLineCapRound;
cPath.lineJoinStyle = kCGLineJoinRound;
UIColor *color = self.unfillColor;
[color setStroke];
[cPath stroke];
}
用法
- (void)setCircle{
ZYCircle *circle = [[ZYCircle alloc] initWithFrame:CGRectMake(30, 20,SCREEN_WIDTH-60 , SCREEN_WIDTH-60)];
circle.percentage = 0.23; //百分比數(shù)值
circle.lineWith = 30; //線寬
circle.fillColor = [UIColor redColor]; //填充顏色
circle.unfillColor = [UIColor lightGrayColor]; //未填充顏色
circle.startAngle = 150; //百分百的圓環(huán)起點(diǎn)
circle.endInnerAngle = 390; //百分百的圓環(huán)終點(diǎn)
// circle.centerLable.text = @"111"; //中心標(biāo)簽的顯示數(shù)值续搀,默認(rèn)為百分?jǐn)?shù)
[self.displayView addSubview:circle];
}
#pragma mark - 點(diǎn)擊方法
- (IBAction)百分比圓環(huán):(id)sender {
[self setCircle];
}