进度圆环—支持点击

离散阶段圆环,支持点击效果,具有很强的扩展性
用法:

#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];

}

运行效果
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_33323291/article/details/52619068
今日推荐