离散阶段圆环,支持点击效果,具有很强的扩展性
用法:
#import "ViewController.h"
#import "XQCircleView.h"
@interface ViewController ()
@property (nonatomic, strong) UILabel *clickLabel;
@property (nonatomic, strong) XQCircleView *circle;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setup];
}
-(void)setup{
CGFloat width = [UIScreen mainScreen].bounds.size.width;
XQCircleView *circle = [[XQCircleView alloc] initWithFrame:CGRectMake(20, 100, width - 40, width - 40)];
circle.dataArray = @[@0.2,@0.2,@0.1,@0.3,@0.2];
circle.circleWidth = 40.0f;
circle.progress = 0.1;
circle.mainColor = [UIColor greenColor];
circle.secondaryColor = [UIColor lightGrayColor];
circle.selectedNum = ^(NSInteger number){
self.clickLabel.text = [NSString stringWithFormat:@"点击了%ld个分块",number];
};
[self.view addSubview:circle];
self.circle = circle;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(width * 0.5 -100, 130 +width - 40 , 200, 25)];
label.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:label];
self.clickLabel = label;
UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(width * 0.5 - 100, 90 + width + 45 , 200, 10)];
[slider addTarget:self action:@selector(clickSliderAction:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:slider];
}
-(void)clickSliderAction:(UISlider *)sender{
self.circle.sliderValue = sender.value;
}
功能实现代码:
#import <UIKit/UIKit.h>
typedef void(^clickSectionNum)(NSInteger number);
@interface XQCircleView : UIView
///圆环各段所占比例
@property (nonatomic, strong) NSArray *dataArray;
///圆环进度百分比
@property (nonatomic, assign) CGFloat progress;
///圆环宽度
@property (nonatomic, assign) CGFloat circleWidth;
///未进行颜色
@property (nonatomic, strong) UIColor *secondaryColor;
///已进行颜色
@property (nonatomic, strong) UIColor *mainColor;
@property (nonatomic, copy) clickSectionNum selectedNum;
@property (nonatomic, assign) CGFloat sliderValue;
@end
#import "XQCircleView.h"
#define separeteAngle 2
@interface XQCircleView ()
@end
@implementation XQCircleView
-(instancetype)initWithFrame:(CGRect)frame{
if ([super initWithFrame:frame]) {
self.backgroundColor = [UIColor whiteColor];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapAction:)];
[self addGestureRecognizer:tap];
}
return self;
}
- (void)drawRect:(CGRect)rect {
NSUInteger sectionCount = self.dataArray.count;
CGFloat wh = rect.size.width * 0.5;
CGPoint center = CGPointMake(wh, wh);
CGFloat innerRadius = wh - _circleWidth;
CGFloat outerRadius = wh;
///每一度间隔所占度数
CGFloat seperate = (separeteAngle * 2 * M_PI) / 360;
CGFloat startAngle = -M_PI_2 + seperate * 0.5;
///底层颜色绘制
for (NSUInteger i = 0; i < sectionCount; i ++) {
CGFloat percentA = [self.dataArray[i] floatValue];
CGFloat result = percentA * (360 - sectionCount * separeteAngle);
CGFloat outResult = (result * 2 * M_PI)/360;
CGFloat endAngle = startAngle + outResult;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:outerRadius startAngle:startAngle endAngle: endAngle clockwise:YES];
[path addArcWithCenter:center radius:innerRadius startAngle:endAngle endAngle:startAngle clockwise:NO];
[self.secondaryColor set];
[path fill];
startAngle += seperate + outResult;
}
///进度颜色绘制
//计算得出阶段总数
NSInteger totalP = 0;
CGFloat sumP = 0.0f;
for (NSUInteger i = 0; i <sectionCount; i ++) {
CGFloat percentA = [self.dataArray[i] floatValue];
totalP += 1;
sumP += percentA;
if (sumP >= self.progress) {
break;
}
}
///进度颜色绘制
CGFloat sumPer = 0.0f;
for (NSUInteger i = 0; i < totalP; i ++) {
CGFloat percentA = [self.dataArray[i] floatValue];
if (i == totalP - 1) {
percentA = self.progress - sumPer;
}
sumPer += percentA;
CGFloat result = percentA * (360 - sectionCount * separeteAngle);
CGFloat outResult = (result * 2 * M_PI)/360;
CGFloat endAngle = startAngle + outResult;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:outerRadius startAngle:startAngle endAngle: endAngle clockwise:YES];
[path addArcWithCenter:center radius:innerRadius startAngle:endAngle endAngle:startAngle clockwise:NO];
[self.mainColor set];
[path fill];
startAngle += seperate + outResult;
}
}
-(void)handleTapAction:(UITapGestureRecognizer *)tap{
CGFloat width = self.bounds.size.width;
CGPoint C = [tap locationInView:tap.view];
CGPoint A = CGPointMake(width * 0.5, 0.0);
CGPoint B = CGPointMake(width* 0.5, width * 0.5);
CGFloat a=[self distancepointA:B pointB:C];
CGFloat b=[self distancepointA:A pointB:C];
CGFloat c=[self distancepointA:B pointB:A];
CGFloat corB = (a * a + c * c - b* b) /(2*a*c);
CGFloat currentCor = acosf(corB);
if (a > (width* 0.5 - _circleWidth) && a < width * 0.5) {
if (C.x < width * 0.5) {
//在左侧情况下
currentCor = 2 * M_PI - currentCor;
}
NSInteger clickNum = 0;
CGFloat sumBefore = 0.0f;
NSUInteger sectionCount = self.dataArray.count;
CGFloat seperate = (separeteAngle * 2 * M_PI) / 360;
CGFloat startAngle = seperate * 0.5;
for (NSUInteger i = 0; i < sectionCount; i ++) {
CGFloat percentA = [self.dataArray[i] floatValue];
CGFloat result = percentA * (360 - sectionCount * separeteAngle);
CGFloat outResult = (result * 2 * M_PI)/360;
CGFloat endAngle = startAngle + outResult;
if (currentCor < endAngle && currentCor > startAngle) {
break;
}else{
clickNum += 1;
sumBefore += percentA;
startAngle += seperate + outResult;
}
}
self.selectedNum(clickNum);
}
}
///计算两点之间的距离
-(CGFloat)distancepointA:(CGPoint)pointA pointB:(CGPoint)pointB{
CGFloat dis = (pointA.x - pointB.x)*(pointA.x - pointB.x) + (pointA.y - pointB.y)*(pointA.y - pointB.y);
return sqrtf(dis);
}
-(void)setSliderValue:(CGFloat)sliderValue{
self.progress = sliderValue;
[self setNeedsDisplay];
}
运行效果