You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

156 lines
4.6 KiB

//
// PathView.m
// WeiChaoTest
//
// Created by WeiChao on 17/8/31.
// Copyright © 2017年 Dinotech. All rights reserved.
//
#import "PathView.h"
#import <QuartzCore/QuartzCore.h>
#define RYUIColorWithRGB(r,g,b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
@implementation PathView
/**
创建 环型弧度 颜色渐变 曲线的 动画
@param frame frame
@return instancetype
*/
- (instancetype)initWithFrame:(CGRect)frame LineWidth:(CGFloat)lineWidth
{
self = [super initWithFrame:frame];
if (self) {
_lineWidth = lineWidth;
//绘制背景
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.lineWidth = lineWidth;
shapeLayer.strokeColor = [[UIColor lightGrayColor] CGColor];
shapeLayer.opacity = 0.2;
shapeLayer.fillColor = [[UIColor clearColor] CGColor];
UIBezierPath *backPath = [UIBezierPath new];
[backPath addArcWithCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:(frame.size.width-PROGRESS_LINE_WIDTH)/2-5 startAngle:-M_PI / 2.0 endAngle:M_PI / 2 * 3 clockwise:YES];
shapeLayer.path = backPath.CGPath;
[self.layer addSublayer:shapeLayer];
}
return self;
}
/**
运行动画
@@param startColor 起始颜色
@param endColor 终止颜色
@param animationDuration 动画时长
@param delay 延迟执行秒数
*/
- (void)StartAnimationWithStartColor:(UIColor*)startColor EndColor:(UIColor*)endColor NumberOfTurns:(double)turns AnimationDuration:(CGFloat)animationDuration Delay:(CGFloat)delay{
_startColor = startColor;
_endColor = endColor;
_turns = turns;
_animationDuration = animationDuration;
[self performSelector:@selector(StartAnimation) withObject:nil afterDelay:delay];
}
-(void)StartAnimation{
CGRect frame = self.frame;
if (_progressLayer) {
[_progressLayer removeFromSuperlayer];
}
//遮罩层
_progressLayer = [CAShapeLayer layer];
_progressLayer.frame = self.bounds;
_progressLayer.fillColor = [[UIColor clearColor] CGColor];
_progressLayer.strokeColor= _endColor.CGColor;
_progressLayer.lineCap = kCALineCapRound;
_progressLayer.lineWidth = _lineWidth;
if(_grain){
[_grain removeFromSuperlayer];
}
//渐变图层
_grain = [CAShapeLayer layer];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
//渐变的颜色
[gradientLayer setColors:[NSArray arrayWithObjects:(id)_startColor.CGColor,(id)_endColor.CGColor, nil]];
[gradientLayer setLocations:@[@0,@0.8,@1]];
[gradientLayer setStartPoint:CGPointMake(0, 1)];
[gradientLayer setEndPoint:CGPointMake(1, 0)];
[_grain addSublayer:gradientLayer];
//用progressLayer来截取渐变层 遮罩
[_grain setMask:_progressLayer];
[self.layer addSublayer:_grain];
// 完整的圈数
int completeTurn = (int)_turns;
//剩余的不足一圈的圈数
double remainingTurn = _turns - completeTurn;
UIBezierPath *path;
//从什么角度开始
double startAngle = 270;
if(completeTurn != 0){
//超过一圈
path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:(frame.size.width-PROGRESS_LINE_WIDTH)/2-5 startAngle:degressToRadius(startAngle) endAngle:degressToRadius(startAngle-0.1) clockwise:YES];
}else{
//不超过一圈
//需要转动的 角度
double changeAngle = (360*remainingTurn);
path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:(frame.size.width-PROGRESS_LINE_WIDTH)/2-5 startAngle:degressToRadius(startAngle) endAngle:degressToRadius(startAngle+changeAngle) clockwise:YES];
}
//增加动画
CABasicAnimation *pathAnimation=[CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration = _animationDuration;
pathAnimation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
pathAnimation.fromValue=[NSNumber numberWithFloat:0.0f];
pathAnimation.toValue=[NSNumber numberWithFloat:1.0f];
pathAnimation.fillMode = kCAFillModeForwards ;
pathAnimation.autoreverses=NO;
_progressLayer.path=path.CGPath;
[_progressLayer addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
}
@end