ifish/Ifish/views/HKPieChartView/HKPieChartView.m

277 lines
8.9 KiB
Objective-C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// HKPieChartView.m
// PieChart
//
// Created by hukaiyin on 16/6/20.
// Copyright © 2016年 HKY. All rights reserved.
//
#import "HKPieChartView.h"
#define Cycle_DarkBlue RGB(0, 150, 200)
#define Cycle_LightBlue RGB(160, 200, 255)
@interface HKPieChartView()<CAAnimationDelegate>
@property (nonatomic, strong) CAShapeLayer *trackLayer;
@property (nonatomic, strong) CAShapeLayer *progressLayer;
@property (nonatomic, strong) CAGradientLayer *gradientLayer;
@property (nonatomic, assign) UIColor *trackColor;
@property (nonatomic, assign) UIColor *progressColor;
@property (nonatomic, assign) CGFloat lineWidth;
@property (nonatomic, strong) UIBezierPath *path;
@property (nonatomic, assign) CGFloat percent; //饼状图显示的百分比最大为100
@property (nonatomic, assign) CGFloat animationDuration;//动画持续时长
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong) UIImageView *shadowImageView;
@property (nonatomic, assign) CGFloat pathWidth;
@property (nonatomic, assign) CGFloat sumSteps;
@property (nonatomic, strong) UILabel *progressLabel;
@property (nonatomic, assign) BOOL panAnimationing;
@end
@implementation HKPieChartView
#pragma mark - Life Cycle
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self updateUI];
}
return self;
}
-(void)awakeFromNib {
[super awakeFromNib];
[self updateUI];
}
- (void)updateUI {
self.trackColor = [UIColor clearColor];
self.progressColor = Cycle_DarkBlue;
self.animationDuration = 1;
self.pathWidth = self.frame.size.width - kSizeFrom750(8);
[self shadowImageView];
[self trackLayer];
[self gradientLayer];
[self loadGesture];
}
- (void)endProgressWithString:(NSString *)text{
self.progressLabel.text = text;
}
- (void)dealloc {
[self invalidateTimer];
}
- (void)removeFromSuperview {
[super removeFromSuperview];
[self invalidateTimer];
}
#pragma mark - Load
- (void)loadLayer:(CAShapeLayer *)layer WithColor:(UIColor *)color {
CGFloat layerWidth = self.pathWidth;
CGFloat layerX = (self.bounds.size.width - layerWidth)/2;
layer.frame = CGRectMake(layerX, layerX, layerWidth, layerWidth);
layer.fillColor = [UIColor clearColor].CGColor;
layer.strokeColor = color.CGColor;
layer.lineCap = kCALineCapButt;
layer.lineWidth = self.lineWidth;
layer.path = self.path.CGPath;
}
- (void)loadGesture {
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(didPan:)];
[self addGestureRecognizer:pan];
}
#pragma mark - Gesture Action
- (void)didPan:(UIPanGestureRecognizer *)pan {
if (!self.panAnimationing) {
}
}
-(void)setInCounting:(BOOL)inCounting{
_inCounting = inCounting;
}
#pragma mark - Animation
- (void)updatePercent:(CGFloat)percent animation:(BOOL)animationed {
self.percent = percent;
[self.progressLayer removeAllAnimations];
if (!animationed) {
[CATransaction begin];
[CATransaction setDisableActions:YES];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[CATransaction setAnimationDuration:1];
self.progressLayer.strokeEnd = self.percent / 100.0;
[CATransaction commit];
} else {
CABasicAnimation *animation= [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.fromValue = @(0.0);
animation.toValue = @(self.percent / 100.f);
animation.duration = self.animationDuration * self.percent / 100;
animation.removedOnCompletion = YES;
animation.delegate = self;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
self.progressLayer.strokeEnd = self.percent / 100;
[self.progressLayer addAnimation:animation forKey:@"strokeEndAnimation"];
}
}
#pragma mark - CAAnimationDelegate
- (void)animationDidStart:(CAAnimation *)anim {
// self.progressLabel.text = @"设备连接中...";
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
// if (flag) {
// [self invalidateTimer];
// if (self.inCounting&&self.percent==0) {
// self.progressLabel.text = @"未开始";
// }else
// {
// self.progressLabel.text = [NSString stringWithFormat:@"%.0f%%", self.percent];
// }
// }
}
- (void)timerAction {
id strokeEnd = [[_progressLayer presentationLayer] valueForKey:@"strokeEnd"];
if (![strokeEnd isKindOfClass:[NSNumber class]]) {
return;
}
CGFloat progress = [strokeEnd floatValue];
if (self.inCounting&&progress==0) {
self.progressLabel.text = @"未开始";
}else
{
NSLog(@"%.2f",progress);
self.progressLabel.text = [NSString stringWithFormat:@"%.0f%%",floorf(progress * 100)];
if (progress>0.5) {
[self updatePercent:100 animation:NO];
}
}
}
- (void)invalidateTimer {
if (!self.timer) {
return;
}
[self.timer invalidate];
self.timer = nil;
}
#pragma mark - Getters & Setters
- (CAShapeLayer *)trackLayer {
if (!_trackLayer) {
_trackLayer = [CAShapeLayer layer];
[self loadLayer:_trackLayer WithColor:self.trackColor];
[self.layer addSublayer:_trackLayer];
}
return _trackLayer;
}
- (UIImageView *)shadowImageView {
if (!_shadowImageView) {
_shadowImageView = [[UIImageView alloc]initWithFrame:self.bounds];
CGPoint center = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);
CGFloat radius = (self.frame.size.width- kSizeFrom750(8)*2)/2;
CGFloat startA = -M_PI_2; //设置进度条起点位置
CGFloat endA =-M_PI_2+ M_PI * 2; //设置进度条终点位置
//获取环形路径画一个圆形填充色透明设置线框宽度为10这样就获得了一个环形
CAShapeLayer * _backLayer = [CAShapeLayer layer];//创建一个track shape layer
_backLayer.frame = self.bounds;
_backLayer.fillColor = [[UIColor clearColor] CGColor]; //填充色为无色
_backLayer.strokeColor = [Cycle_LightBlue CGColor]; //指定path的渲染颜色,这里可以设置任意不透明颜色-淡蓝色
_backLayer.opacity = 1; //背景颜色的透明度
_backLayer.lineCap = kCALineCapRound;//指定线的边缘是圆的
_backLayer.lineWidth = kSizeFrom750(8);//线的宽度
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];//上面说明过了用来构建圆
_backLayer.path =[path CGPath]; //把path传递給layer然后layer会处理相应的渲染整个逻辑和CoreGraph是一致的。
[_shadowImageView.layer addSublayer:_backLayer];
[self addSubview:_shadowImageView];
}
return _shadowImageView;
}
- (CAShapeLayer *)progressLayer {
if (!_progressLayer) {
_progressLayer = [CAShapeLayer layer];
[self loadLayer:_progressLayer WithColor:self.progressColor];
_progressLayer.lineCap = kCALineCapRound;
_progressLayer.strokeEnd = 0;
}
return _progressLayer;
}
- (CAGradientLayer *)gradientLayer {
if (!_gradientLayer) {
_gradientLayer = [CAGradientLayer layer];
_gradientLayer.frame = self.bounds;
// _gradientLayer.colors = @[(id)Cycle_DarkBlue.CGColor,(id)HEXCOLOR(@"#3b82f6").CGColor];
_gradientLayer.colors = @[(id)Cycle_DarkBlue.CGColor,(id)Cycle_DarkBlue.CGColor];
[_gradientLayer setStartPoint:CGPointMake(0.5, 1.0)];
[_gradientLayer setEndPoint:CGPointMake(0.5, 0.0)];
[_gradientLayer setMask:self.progressLayer];
[self.layer addSublayer:_gradientLayer];
}
return _gradientLayer;
}
- (UILabel *)progressLabel {
if (!_progressLabel) {
_progressLabel = [[UILabel alloc]initWithFrame:self.bounds];
_progressLabel.textColor = Cycle_DarkBlue;
_progressLabel.textAlignment = NSTextAlignmentCenter;
_progressLabel.font = FontSize(14);
_progressLabel.text = @"设备连接中...";
[self addSubview:_progressLabel];
}
return _progressLabel;
}
- (void)setPercent:(CGFloat)percent {
_percent = percent;
_percent = _percent > 100 ? 100 : _percent;
_percent = _percent < 0 ? 0 : _percent;
}
- (UIBezierPath *)path {
if (!_path) {
CGFloat halfWidth = self.pathWidth / 2;
_path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(halfWidth, halfWidth)
radius:(self.pathWidth - self.lineWidth)/2
startAngle:-M_PI/2
endAngle:M_PI/2*3
clockwise:YES];
}
return _path;
}
- (CGFloat)lineWidth {
if (_lineWidth == 0) {
_lineWidth = kSizeFrom750(8);
}
return _lineWidth;
}
@end