一个非常轻量级自定义的HUD
2016-12-14 18:34
337 查看
今天呢给同学带来的是一个非常轻量级的自定义HUD,该项目借鉴与别人的项目,目前还不够完善,后期会一步一步完善属于我个人的一个框架!可用于加载界面或者刷新界面!那么我们废话不多说直接上代码,先看效果图!
//
// ZZCircleView.h
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
@interface ZZCircleView :
CALayer
@property (nonatomic,
assign) CGFloat factor;
@end
//
// ZZCircleView.m
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZCircleView.h"
@interface
ZZCircleView()
@property (nonatomic,
assign) CGSize circleRectSize;
@end
@implementation ZZCircleView
#pragma mark - 构造方法初始化
- (instancetype)init
{
if (self = [super
init]) {
self.factor =
0;
self.masksToBounds =
NO;
self.contentsScale = [UIScreen
mainScreen].scale;
}
return
self;
}
#pragma mark - 重写frame方法
- (void)setFrame:(CGRect)frame
{
[super
setFrame:frame];
self.circleRectSize = frame.size;
[self
setNeedsDisplay];
}
#pragma mark - 根据key值来调用super的方法
+ (BOOL)needsDisplayForKey:(NSString *)key
{
if ([key
isEqualToString:@"factor"]) {
return
YES;
}
return [super
needsDisplayForKey:key];
}
#pragma mark - 在上下文中绘制
- (void)drawInContext:(CGContextRef)ctx
{
// width + 1/6*width * 2 = S
CGFloat percent = (1+1.0/6*2);
CGSize dotSize =
CGSizeMake(self.frame.size.width/percent,
self.frame.size.height/percent);
//NSLog(@"%f",_factor);
CGFloat offset = dotSize.width /
3.6;
CGFloat moveDistance = dotSize.width *
1/6 *
_factor;
CGPoint center =
CGPointMake(self.frame.size.width/2,
self.frame.size.height/2);
CGPoint pointA =
CGPointMake(center.x,center.y-dotSize.height/2+moveDistance);
CGPoint pointB =
CGPointMake(center.x+dotSize.width/2+moveDistance,
center.y);
CGPoint pointC =
CGPointMake(center.x, center.y+dotSize.height/2-moveDistance);
CGPoint pointD =
CGPointMake(center.x-dotSize.width/2-moveDistance,
center.y);
CGPoint c1 =
CGPointMake(pointA.x+offset,pointA.y);
CGPoint c2 =
CGPointMake(pointB.x, pointB.y-offset);
CGPoint c3 =
CGPointMake(pointB.x, pointB.y+offset);
CGPoint c4 =
CGPointMake(pointC.x+offset,pointC.y);
CGPoint c5 =
CGPointMake(pointC.x-offset, pointC.y);
CGPoint c6 =
CGPointMake(pointD.x, pointD.y+offset);
CGPoint c7 =
CGPointMake(pointD.x, pointD.y-offset);
CGPoint c8 =
CGPointMake(pointA.x-offset, pointA.y);
UIBezierPath *path = [UIBezierPath
bezierPath];
[path moveToPoint:pointA];
[path addCurveToPoint:pointB
controlPoint1:c1
controlPoint2:c2];
[path addCurveToPoint:pointC
controlPoint1:c3
controlPoint2:c4];
[path addCurveToPoint:pointD
controlPoint1:c5
controlPoint2:c6];
[path addCurveToPoint:pointA
controlPoint1:c7
controlPoint2:c8];
[path closePath];
CGContextAddPath(ctx, path.CGPath);
CGContextSetFillColorWithColor(ctx,[UIColor
whiteColor].CGColor);
CGContextFillPath(ctx);
}
@end
//
// ZZLoaderView.h
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#define ZZCircleStrokWidth 10
#define Radians(x) (M_PI * (x) / 180.0)
#define InsetRadians_between_line M_PI / 6
#define ZZLineAnimationTime 0.8
#define ZZRotateAnimationTime (ZZLineAnimationTime * 4 /
10)
#define ZZFirstDotMoveAnimationTime (ZZLineAnimationTime *
5 / 10)
#define ZZFirstDotRestoreAnimationTime (ZZLineAnimationTime *
6 / 10)
#define ZZCircleRadius 70
#define ZZFirstCircleLength (4 * M_PI + (M_PI/2 - M_PI/12))
#define ZZSecondCircleLength (4 * M_PI +(M_PI/2 - M_PI/12))
#define ZZThirdCircleLength (M_PI*5/4 + M_PI/3)
#define ZZFirstCircelStartAngle (-M_PI/2)
#define ZZFirstCircelEndAngle (4*M_PI - M_PI/12)
#define ZZSecondCircelStartAngle (-M_PI/2)
#define ZZSecondCircelEndAngle (4*M_PI - M_PI/12)
#define ZZThirdCircelStartAngle (-M_PI/3)
#define ZZthirdCircelEndAngle (M_PI+M_PI/5)
#define ZZRGBA(r,g,b,a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f
alpha:a]
#define ZZStrokeWidth 12
#import <UIKit/UIKit.h>
@interface ZZLoaderView :
UIView
- (void)startLoading;
- (void)stopLoading;
@end
//
// ZZLoaderView.m
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZLoaderView.h"
#import "ZZCenterRotateView.h"
@interface
ZZLoaderView() {
double first_Circle_Stage1_StrokeEnd;
double first_Circle_Stage2_StrokeEnd;
double first_Circle_Stage3_StrokeEnd;
double first_Circle_Stage4_StrokeEnd;
double first_Circle_Stage1_StrokeStart;
double first_Circle_Stage2_StrokeStart;
double first_Circle_Stage3_StrokeStart;
double first_Circle_Stage4_StrokeStart;
double second_Circle_Stage1_StrokeEnd;
double second_Circle_Stage2_StrokeEnd;
double second_Circle_Stage3_StrokeEnd;
double second_Circle_Stage4_StrokeEnd;
double second_Circle_Stage1_StrokeStart;
double second_Circle_Stage2_StrokeStart;
double second_Circle_Stage3_StrokeStart;
double second_Circle_Stage4_StrokeStart;
double third_Circle_Stage3_StrokeEnd;
double third_Circle_Stage4_StrokeEnd;
double third_Circle_Stage3_StrokeStart;
double third_Circle_Stage4_StrokeStart;
}
@property(nonatomic,strong)
ZZCenterRotateView *rotateView;
@property(nonatomic,strong)
CAAnimationGroup *firstCircleAnimationGroup;
@property(nonatomic,strong)
CAAnimationGroup *secondCircleAnimationGroup;
@end
@implementation ZZLoaderView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super
initWithFrame:frame]) {
[self
setUpStageValues];
[self
setUpRotateView];
[self
startLoading];
self.backgroundColor = [UIColor
clearColor];
}
return
self;
}
- (void)startLoading {
[self
removeLines];
[self
creatFirstThreePathLayer];
[self
creatSecondThreePathLayer];
}
- (void)stopLoading {
[self.rotateView
removeAnimations];
[self
removeLines];
/* NSArray *sublayers = [self.layer sublayers];
for(CALayer *layer in sublayers) {
[layer removeAllAnimations];
[layer removeFromSuperlayer];
}*/
}
- (void)removeLines {
NSArray *sublayers = [self.layer
sublayers];
NSInteger count = sublayers.count;
for(NSInteger i =
0;i < count;) {
id layer = sublayers[i];
if ([layer
isKindOfClass:[CAShapeLayer
class]]) {
[layer removeAllAnimations];
[layer removeFromSuperlayer];
count -= 1;
} else {
i++;
}
}
}
- (void)setUpRotateView {
CGFloat rotateViewWidth =
ZZCircleRadius +
10;
CGFloat rotateViewHeight = rotateViewWidth;
CGFloat rotateX = (self.frame.size.width
- rotateViewWidth)/2;
CGFloat rotateY = (self.frame.size.height
- rotateViewHeight)/2;
self.rotateView = [[ZZCenterRotateView
alloc] initWithFrame:CGRectMake(rotateX, rotateY, rotateViewWidth, rotateViewHeight)];
__weak
typeof(self) weakSelf =
self ;
self.rotateView.dotAniationFinishHandler
= ^{
[weakSelf startLoading];
};
[self
addSubview:self.rotateView];
}
- (void)setUpStageValues {
double s1 =
ZZFirstCircleLength;
double s2 =
ZZSecondCircleLength;
double s3 =
ZZThirdCircleLength;
first_Circle_Stage1_StrokeEnd = (M_PI+M_PI/8)/s1;
first_Circle_Stage2_StrokeEnd = (4*M_PI-M_PI*1/3)/s1;
first_Circle_Stage3_StrokeEnd = (4*M_PI+M_PI/6)/s1;
first_Circle_Stage4_StrokeEnd =
1;
first_Circle_Stage1_StrokeStart = (M_PI/2-M_PI/6)/s1;
first_Circle_Stage2_StrokeStart = (2*M_PI
+ M_PI/6)/s1;
//同时也是白线起点
first_Circle_Stage3_StrokeStart = (4*M_PI-M_PI/6)/s1;
first_Circle_Stage4_StrokeStart = (s1-M_PI/30)/s1;//1;
second_Circle_Stage1_StrokeEnd = (M_PI+M_PI/8-M_PI/12)/s2;
second_Circle_Stage2_StrokeEnd = (4*M_PI-M_PI*1/3-M_PI/3)/s2;
second_Circle_Stage3_StrokeEnd = (4*M_PI-M_PI/6)/s2;
second_Circle_Stage4_StrokeEnd = (4 *
M_PI )/s2;
second_Circle_Stage1_StrokeStart = (M_PI/2-M_PI/6)/s2;
second_Circle_Stage2_StrokeStart = (2*M_PI
+ M_PI/6)/s2;;
//同时也是白线起点
second_Circle_Stage3_StrokeStart = (4*M_PI-M_PI/6-M_PI/3)/s2;
second_Circle_Stage4_StrokeStart = (4 *
M_PI-M_PI/30)/s2;//(4
* M_PI )/s2;
third_Circle_Stage3_StrokeEnd = (M_PI*5/4)/s3;
third_Circle_Stage4_StrokeEnd =
1;
third_Circle_Stage3_StrokeStart = (M_PI*5/4-M_PI/3)/s3;
third_Circle_Stage4_StrokeStart = (s3 -
M_PI/30)/s3;//1;
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
NSString *animationName = [anim
valueForKey:@"animationName"];
if ([animationName
isEqualToString:@"firstCircleGroup"]) {
} else
if ([animationName
isEqualToString:@""]) {
}
}
/**
* 毫秒
*
* @param mscDelay 毫秒
*/
- (void)startRotateAfterSeconds:(int) mscDelay {
__weak
typeof(self) weakSelf =
self ;
dispatch_time_t delay =
dispatch_time(DISPATCH_TIME_NOW,
NSEC_PER_MSEC *mscDelay);
dispatch_after(delay,
dispatch_get_main_queue(), ^{
[weakSelf.rotateView
rotateAnimation];
});
}
- (void)creatFirstThreePathLayer {
CAShapeLayer *firstCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:firstCirlce];
CAShapeLayer *secondCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:secondCirlce];
CAShapeLayer *thirdCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:thirdCirlce];
/**
* 绿线
*/
UIBezierPath *firstCirlcePath = [self
creatCirclePathWithRadius:ZZCircleRadius
startAngle:ZZFirstCircelStartAngle
endAngle:ZZFirstCircelEndAngle];
firstCirlce.strokeColor =
ZZRGBA(144,
241, 9,
1).CGColor;
firstCirlce.fillColor = [UIColor
clearColor].CGColor;
firstCirlce.lineWidth =
ZZStrokeWidth;
firstCirlce.contentsScale = [UIScreen
mainScreen].scale;
firstCirlce.lineCap =
kCALineCapRound;
firstCirlce.path = firstCirlcePath.CGPath;
firstCirlce.strokeEnd =
0;
firstCirlce.strokeStart =
0;
NSArray<NSNumber*>* firstCirlce_StrokeEnd_Values = [self
create_Fast_First_Cirlce_StrokeEnd_Values];
NSArray<NSNumber*>* firstCirlceTimes = [self
create_Fast_CirlceTimes];
NSArray<NSNumber*>* firstCirlce_StrokeStart_Values = [self
create_Fast_First_Cirlce_StrokeStart_Values];
CAKeyframeAnimation *firstCircle_StrokeEnd_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeEnd"];
firstCircle_StrokeEnd_Animation.values = firstCirlce_StrokeEnd_Values;
firstCircle_StrokeEnd_Animation.keyTimes = firstCirlceTimes;
firstCircle_StrokeEnd_Animation.duration =
ZZLineAnimationTime;
CAKeyframeAnimation *firstCircle_StrokeStart_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeStart"];
firstCircle_StrokeStart_Animation.values = firstCirlce_StrokeStart_Values;
firstCircle_StrokeStart_Animation.keyTimes = firstCirlceTimes;
firstCircle_StrokeStart_Animation.duration =
ZZLineAnimationTime;
CAAnimationGroup *firstCircleGroup = [CAAnimationGroup
animation];
firstCircleGroup.animations =
@[firstCircle_StrokeStart_Animation,firstCircle_StrokeEnd_Animation];
firstCircleGroup.duration =
ZZLineAnimationTime;
firstCircleGroup.delegate =
self ;
// firstCircleGroup.removedOnCompletion = true;
// firstCircleGroup.repeatCount = MAXFLOAT;
[firstCircleGroup setValue:@"firstCircleGroup"
forKey:@"animationName"];
[firstCirlce addAnimation:firstCircleGroup
forKey:nil];
/**
* 黄线
*/
UIBezierPath *secondCirlcePath = [self
creatCirclePathWithRadius:ZZCircleRadius
startAngle:ZZSecondCircelStartAngle
endAngle:ZZSecondCircelEndAngle];
secondCirlce.strokeColor =
ZZRGBA(253,
184, 9,
1).CGColor;
secondCirlce.fillColor = [UIColor
clearColor].CGColor;
secondCirlce.lineWidth =
ZZStrokeWidth;
secondCirlce.contentsScale = [UIScreen
mainScreen].scale;
secondCirlce.lineCap =
kCALineCapRound;
secondCirlce.path = secondCirlcePath.CGPath;
secondCirlce.strokeEnd =
0;
secondCirlce.strokeStart =
0;
NSArray<NSNumber*>* secondCirlce_StrokeEnd_Values = [self
create_Fast_Second_Cirlce_StrokeEnd_Values];
NSArray<NSNumber*> *secondCirlce_StrokeStart_Values = [self
create_Fast_Second_Cirlce_StrokeStart_Values];
NSArray<NSNumber*> *secondCirlceTimes = firstCirlceTimes.copy;
CAKeyframeAnimation *secondCircle_StrokeEnd_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeEnd"];
secondCircle_StrokeEnd_Animation.values = secondCirlce_StrokeEnd_Values;
secondCircle_StrokeEnd_Animation.keyTimes = secondCirlceTimes;
secondCircle_StrokeEnd_Animation.duration =
ZZLineAnimationTime;
CAKeyframeAnimation *secondCircle_StrokeStart_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeStart"];
secondCircle_StrokeStart_Animation.values = secondCirlce_StrokeStart_Values;
secondCircle_StrokeStart_Animation.keyTimes = secondCirlceTimes;
secondCircle_StrokeStart_Animation.duration =
ZZLineAnimationTime;
CAAnimationGroup *secondCircleGroup = [CAAnimationGroup
animation];
secondCircleGroup.animations =
@[secondCircle_StrokeEnd_Animation,secondCircle_StrokeStart_Animation];
secondCircleGroup.duration =
ZZLineAnimationTime;
secondCircleGroup.delegate =
self ;
// secondCircleGroup.removedOnCompletion = true;
// secondCircleGroup.repeatCount = MAXFLOAT;
// [secondCircleGroup setValue:@"firstCircleGroup" forKey:@"animationName"];
[secondCirlce addAnimation:secondCircleGroup
forKey:nil];
[self
startRotateAfterSeconds:ZZLineAnimationTime *
0.2*1000];
}
- (void) creatSecondThreePathLayer {
CAShapeLayer *firstCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:firstCirlce];
CAShapeLayer *secondCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:secondCirlce];
CAShapeLayer *thirdCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:thirdCirlce];
/**
* 绿线
*/
UIBezierPath *firstCirlcePath = [self
creatCirclePathWithRadius:ZZCircleRadius
startAngle:ZZFirstCircelStartAngle
endAngle:ZZFirstCircelEndAngle];
firstCirlce.strokeColor =
ZZRGBA(144,
241, 9,
1).CGColor;
firstCirlce.fillColor = [UIColor
clearColor].CGColor;
firstCirlce.lineWidth =
ZZStrokeWidth;
firstCirlce.contentsScale = [UIScreen
mainScreen].scale;
firstCirlce.lineCap =
kCALineCapRound;
firstCirlce.path = firstCirlcePath.CGPath;
firstCirlce.strokeEnd =
0;
firstCirlce.strokeStart =
0;
NSArray<NSNumber*>* firstCirlce_StrokeEnd_Values = [self
create_Slow_First_Cirlce_StrokeEnd_Values];
NSArray<NSNumber*>* firstCirlceTimes = [self
create_Slow_CirlceTimes];
NSArray<NSNumber*>* firstCirlce_StrokeStart_Values = [self
create_Slow_First_Cirlce_StrokeStart_Values];
CAKeyframeAnimation *firstCircle_StrokeEnd_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeEnd"];
firstCircle_StrokeEnd_Animation.values = firstCirlce_StrokeEnd_Values;
firstCircle_StrokeEnd_Animation.keyTimes = firstCirlceTimes;
firstCircle_StrokeEnd_Animation.duration =
ZZLineAnimationTime;
CAKeyframeAnimation *firstCircle_StrokeStart_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeStart"];
firstCircle_StrokeStart_Animation.values = firstCirlce_StrokeStart_Values;
firstCircle_StrokeStart_Animation.keyTimes = firstCirlceTimes;
firstCircle_StrokeStart_Animation.duration =
ZZLineAnimationTime;
CAAnimationGroup *firstCircleGroup = [CAAnimationGroup
animation];
firstCircleGroup.animations =
@[firstCircle_StrokeStart_Animation,firstCircle_StrokeEnd_Animation];
firstCircleGroup.duration =
ZZLineAnimationTime;
firstCircleGroup.delegate =
self ;
// firstCircleGroup.removedOnCompletion = true;
[firstCircleGroup setValue:@"secondCircleGroup"
forKey:@"animationName"];
// firstCircleGroup.repeatCount = MAXFLOAT;
[firstCirlce addAnimation:firstCircleGroup
forKey:nil];
/**
* 黄线
*/
UIBezierPath *secondCirlcePath = [self
creatCirclePathWithRadius:ZZCircleRadius
startAngle:ZZSecondCircelStartAngle
endAngle:ZZSecondCircelEndAngle];
secondCirlce.strokeColor =
ZZRGBA(253,
184, 9,
1).CGColor;
secondCirlce.fillColor = [UIColor
clearColor].CGColor;
secondCirlce.lineWidth =
ZZStrokeWidth;
secondCirlce.contentsScale = [UIScreen
mainScreen].scale;
secondCirlce.lineCap =
kCALineCapRound;
secondCirlce.path = secondCirlcePath.CGPath;
secondCirlce.strokeEnd =
0;
secondCirlce.strokeStart =
0;
NSArray<NSNumber*>* secondCirlce_StrokeEnd_Values = [self
create_Slow_Second_Cirlce_StrokeEnd_Values];
NSArray<NSNumber*> *secondCirlce_StrokeStart_Values = [self
create_Slow_Second_Cirlce_StrokeStart_Values];
NSArray<NSNumber*> *secondCirlceTimes = firstCirlceTimes.copy;
CAKeyframeAnimation *secondCircle_StrokeEnd_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeEnd"];
secondCircle_StrokeEnd_Animation.values = secondCirlce_StrokeEnd_Values;
secondCircle_StrokeEnd_Animation.keyTimes = secondCirlceTimes;
secondCircle_StrokeEnd_Animation.duration =
ZZLineAnimationTime;
CAKeyframeAnimation *secondCircle_StrokeStart_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeStart"];
secondCircle_StrokeStart_Animation.values = secondCirlce_StrokeStart_Values;
secondCircle_StrokeStart_Animation.keyTimes = secondCirlceTimes;
secondCircle_StrokeStart_Animation.duration =
ZZLineAnimationTime;
CAAnimationGroup *secondCircleGroup = [CAAnimationGroup
animation];
secondCircleGroup.animations =
@[secondCircle_StrokeEnd_Animation,secondCircle_StrokeStart_Animation];
secondCircleGroup.duration =
ZZLineAnimationTime;
secondCircleGroup.delegate =
self ;
// secondCircleGroup.removedOnCompletion = true;
//secondCircleGroup.repeatCount = MAXFLOAT;
//[secondCircleGroup setValue:@"firstCircleGroup" forKey:@"animationName"];
[secondCirlce addAnimation:secondCircleGroup
forKey:nil];
/**
* 白线
*/
UIBezierPath *thirdCirlcePath = [self
creatCirclePathWithRadius:ZZCircleRadius
startAngle:ZZThirdCircelStartAngle
endAngle:ZZthirdCircelEndAngle];
thirdCirlce.strokeColor = [[UIColor
whiteColor] CGColor];
thirdCirlce.fillColor = [UIColor
clearColor].CGColor;
thirdCirlce.lineWidth =
ZZStrokeWidth;
thirdCirlce.contentsScale = [UIScreen
mainScreen].scale;
thirdCirlce.lineCap =
kCALineCapRound;
thirdCirlce.path = thirdCirlcePath.CGPath;
thirdCirlce.strokeEnd =
0;
thirdCirlce.strokeStart =
0;
NSArray<NSNumber*>* thirdCirlce_StrokeEnd_Values = [self
create_Third_Cirlce_StrokeEnd_Values];
NSArray<NSNumber*> *thirdCirlce_StrokeStart_Values = [self
create_Third_Cirlce_StrokeStart_Values];
NSArray<NSNumber*> *thirdCirlceTimes = firstCirlceTimes.copy;
CAKeyframeAnimation *thirdCircle_StrokeEnd_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeEnd"];
thirdCircle_StrokeEnd_Animation.values = thirdCirlce_StrokeEnd_Values;
thirdCircle_StrokeEnd_Animation.keyTimes = thirdCirlceTimes;
thirdCircle_StrokeEnd_Animation.duration =
ZZLineAnimationTime;
CAKeyframeAnimation *thirdCircle_StrokeStart_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeStart"];
thirdCircle_StrokeStart_Animation.values = thirdCirlce_StrokeStart_Values;
thirdCircle_StrokeStart_Animation.keyTimes = thirdCirlceTimes;
thirdCircle_StrokeStart_Animation.duration =
ZZLineAnimationTime;
CAAnimationGroup *thirdCircleGroup = [CAAnimationGroup
animation];
thirdCircleGroup.animations =
@[thirdCircle_StrokeEnd_Animation,thirdCircle_StrokeStart_Animation];
thirdCircleGroup.duration =
ZZLineAnimationTime;
thirdCircleGroup.delegate =
self ;
// thirdCircleGroup.removedOnCompletion = true;
// thirdCircleGroup.repeatCount = MAXFLOAT;
// [thirdCircleGroup setValue:@"thirdCircleGroup" forKey:@"animationName"];
[thirdCirlce addAnimation:thirdCircleGroup
forKey:nil];
}
- (UIBezierPath*)creatCirclePathWithRadius: (double)radius startAngle:(double)startAngle
endAngle:(double)endAngle {
UIBezierPath *path ;
path = [UIBezierPath
bezierPathWithArcCenter:CGPointMake(self.frame.size.width/2,
self.frame.size.height/2)
radius:radius startAngle:startAngle
endAngle:endAngle
clockwise:YES];
return path;
}
#pragma mark 第一个圈圈(快和慢)
- (NSArray<NSNumber*>*)create_Fast_First_Cirlce_StrokeEnd_Values {
double firstCirlce_Stage0_StrokeEnd =
0;
double firstCirlce_Stage1_StrokeEnd =
first_Circle_Stage1_StrokeEnd;
double firstCirlce_Stage2_StrokeEnd =
first_Circle_Stage2_StrokeEnd;
double firstCirlce_Stage3_StrokeEnd =
first_Circle_Stage3_StrokeEnd;
double firstCirlce_Stage4_StrokeEnd =
first_Circle_Stage4_StrokeEnd;
NSArray<NSNumber*>* firstCirlce_StrokeEnd_Values =
@[@(firstCirlce_Stage0_StrokeEnd),
@(firstCirlce_Stage1_StrokeEnd),
@(firstCirlce_Stage2_StrokeEnd),
@(firstCirlce_Stage3_StrokeEnd),
@(firstCirlce_Stage4_StrokeEnd)];
return firstCirlce_StrokeEnd_Values;
}
- (NSArray<NSNumber*>*)create_Fast_First_Cirlce_StrokeStart_Values {
double firstCirlce_Stage0_StrokeStart =
0;
double firstCirlce_Stage1_StrokeStart =
first_Circle_Stage1_StrokeStart;
double firstCirlce_Stage2_StrokeStart =
first_Circle_Stage2_StrokeStart;
double firstCirlce_Stage3_StrokeStart =
first_Circle_Stage3_StrokeStart;
double firstCirlce_Stage4_StrokeStart =
first_Circle_Stage4_StrokeStart;
NSArray<NSNumber*>* firstCirlce_StrokeStart_Values =
@[@(firstCirlce_Stage0_StrokeStart),
@(firstCirlce_Stage1_StrokeStart),
@(firstCirlce_Stage2_StrokeStart),
@(firstCirlce_Stage3_StrokeStart),
@(firstCirlce_Stage4_StrokeStart)];
return firstCirlce_StrokeStart_Values;
}
- (NSArray<NSNumber*>*)create_Fast_CirlceTimes {
double firstCirlce_Stage0_Stroke_Time =
0.0/10;
double firstCirlce_Stage1_Stroke_Time =
2.0/10;
double firstCirlce_Stage2_Stroke_Time = (6.0)/10;
double firstCirlce_Stage3_Stroke_Time = (8.1)/10;
double firstCirlce_Stage4_Stroke_Time = (10.0)/10;
NSArray<NSNumber*>* firstCirlceTimes =
@[@(firstCirlce_Stage0_Stroke_Time),
@(firstCirlce_Stage1_Stroke_Time),
@(firstCirlce_Stage2_Stroke_Time),
@(firstCirlce_Stage3_Stroke_Time),
@(firstCirlce_Stage4_Stroke_Time)];
return firstCirlceTimes;
}
- (NSArray<NSNumber*>*)create_Slow_First_Cirlce_StrokeEnd_Values {
double firstCirlce_Stage0_StrokeEnd =
0;
double firstCirlce_Stage1_StrokeEnd =
0;
double firstCirlce_Stage2_StrokeEnd =
first_Circle_Stage1_StrokeEnd;
double firstCirlce_Stage3_StrokeEnd =
first_Circle_Stage2_StrokeEnd;
double firstCirlce_Stage4_StrokeEnd =
first_Circle_Stage3_StrokeEnd;
double firstCirlce_Stage5_StrokeEnd =
first_Circle_Stage4_StrokeEnd;
NSArray<NSNumber*>* firstCirlce_StrokeEnd_Values =
@[@(firstCirlce_Stage0_StrokeEnd),
@(firstCirlce_Stage1_StrokeEnd),
@(firstCirlce_Stage2_StrokeEnd),
@(firstCirlce_Stage3_StrokeEnd),
@(firstCirlce_Stage4_StrokeEnd),
@(firstCirlce_Stage5_StrokeEnd)];
return firstCirlce_StrokeEnd_Values;
}
- (NSArray<NSNumber*>*)create_Slow_CirlceTimes {
double firstCirlce_Stage0_Stroke_Time =
0.0/10.0;
double firstCirlce_Stage1_Stroke_Time =
1.0/10;
double firstCirlce_Stage2_Stroke_Time = (3.0)/10;
double firstCirlce_Stage3_Stroke_Time = (6.0)/10;
double firstCirlce_Stage4_Stroke_Time = (8.1)/10;
double firstCirlce_Stage5_Stroke_Time = (10.0)/10;
NSArray<NSNumber*>* firstCirlceTimes =
@[@(firstCirlce_Stage0_Stroke_Time),
@(firstCirlce_Stage1_Stroke_Time),
@(firstCirlce_Stage2_Stroke_Time),
@(firstCirlce_Stage3_Stroke_Time),
@(firstCirlce_Stage4_Stroke_Time),
@(firstCirlce_Stage5_Stroke_Time)];
return firstCirlceTimes;
}
- (NSArray<NSNumber*>*)create_Slow_First_Cirlce_StrokeStart_Values {
double firstCirlce_Stage0_StrokeStart =
0;
double firstCirlce_Stage1_StrokeStart =
0;
double firstCirlce_Stage2_StrokeStart =
first_Circle_Stage1_StrokeStart;
double firstCirlce_Stage3_StrokeStart =
first_Circle_Stage2_StrokeStart;
double firstCirlce_Stage4_StrokeStart =
first_Circle_Stage3_StrokeStart;
double firstCirlce_Stage5_StrokeStart =
first_Circle_Stage4_StrokeStart;
NSArray<NSNumber*>* firstCirlce_StrokeStart_Values =
@[@(firstCirlce_Stage0_StrokeStart),
@(firstCirlce_Stage1_StrokeStart),
@(firstCirlce_Stage2_StrokeStart),
@(firstCirlce_Stage3_StrokeStart),
@(firstCirlce_Stage4_StrokeStart),
@(firstCirlce_Stage5_StrokeStart)];
return firstCirlce_StrokeStart_Values;
}
#pragma mark 第二个圈圈(快和慢)
- (NSArray<NSNumber*>*)create_Fast_Second_Cirlce_StrokeEnd_Values {
double secondCirlce_Stage0_StrokeEnd =
0;
double secondCirlce_Stage1_StrokeEnd =
second_Circle_Stage1_StrokeEnd;
double secondCirlce_Stage2_StrokeEnd =
second_Circle_Stage2_StrokeEnd;
double secondCirlce_Stage3_StrokeEnd =
second_Circle_Stage3_StrokeEnd;
double secondCirlce_Stage4_StrokeEnd =
second_Circle_Stage4_StrokeEnd;
NSArray<NSNumber*>* secondCirlce_StrokeEnd_Values =
@[@(secondCirlce_Stage0_StrokeEnd),
@(secondCirlce_Stage1_StrokeEnd),
@(secondCirlce_Stage2_StrokeEnd),
@(secondCirlce_Stage3_StrokeEnd),
@(secondCirlce_Stage4_StrokeEnd)];
return secondCirlce_StrokeEnd_Values;
}
- (NSArray<NSNumber*>*)create_Fast_Second_Cirlce_StrokeStart_Values {
double secondCirlce_Stage0_StrokeStart =
0;
double secondCirlce_Stage1_StrokeStart =
second_Circle_Stage1_StrokeStart;
double secondCirlce_Stage2_StrokeStart =
second_Circle_Stage2_StrokeStart;
double secondCirlce_Stage3_StrokeStart =
second_Circle_Stage3_StrokeStart;
double secondCirlce_Stage4_StrokeStart =
second_Circle_Stage4_StrokeStart;
NSArray<NSNumber*> *secondCirlce_StrokeStart_Values =
@[@(secondCirlce_Stage0_StrokeStart),
@(secondCirlce_Stage1_StrokeStart),
@(secondCirlce_Stage2_StrokeStart),
@(secondCirlce_Stage3_StrokeStart),
@(secondCirlce_Stage4_StrokeStart)];
return secondCirlce_StrokeStart_Values;
}
- (NSArray<NSNumber*>*)create_Slow_Second_Cirlce_StrokeEnd_Values {
double secondCirlce_Stage0_StrokeEnd =
0;
double secondCirlce_Stage1_StrokeEnd =
0;
double secondCirlce_Stage2_StrokeEnd =
second_Circle_Stage1_StrokeEnd;
double secondCirlce_Stage3_StrokeEnd =
second_Circle_Stage2_StrokeEnd;
double secondCirlce_Stage4_StrokeEnd =
second_Circle_Stage3_StrokeEnd;
double secondCirlce_Stage5_StrokeEnd =
second_Circle_Stage4_StrokeEnd;
NSArray<NSNumber*>* secondCirlce_StrokeEnd_Values =
@[@(secondCirlce_Stage0_StrokeEnd),
@(secondCirlce_Stage1_StrokeEnd),
@(secondCirlce_Stage2_StrokeEnd),
@(secondCirlce_Stage3_StrokeEnd),
@(secondCirlce_Stage4_StrokeEnd),
@(secondCirlce_Stage5_StrokeEnd)];
return secondCirlce_StrokeEnd_Values;
}
- (NSArray<NSNumber*>*)create_Slow_Second_Cirlce_StrokeStart_Values {
double secondCirlce_Stage0_StrokeStart =
0;
double secondCirlce_Stage1_StrokeStart =
0;
double secondCirlce_Stage2_StrokeStart =
second_Circle_Stage1_StrokeStart;
double secondCirlce_Stage3_StrokeStart =
second_Circle_Stage2_StrokeStart;
double secondCirlce_Stage4_StrokeStart =
second_Circle_Stage3_StrokeStart;
double secondCirlce_Stage5_StrokeStart =
second_Circle_Stage4_StrokeStart;
NSArray<NSNumber*> *secondCirlce_StrokeStart_Values =
@[@(secondCirlce_Stage0_StrokeStart),
@(secondCirlce_Stage1_StrokeStart),
@(secondCirlce_Stage2_StrokeStart),
@(secondCirlce_Stage3_StrokeStart),
@(secondCirlce_Stage4_StrokeStart),
@(secondCirlce_Stage5_StrokeStart)];
return secondCirlce_StrokeStart_Values;
}
#pragma mark 第三个圈圈(快和慢)
- (NSArray<NSNumber*>*)create_Third_Cirlce_StrokeEnd_Values {
double thirdCirlce_Stage0_StrokeEnd =
0;
double thirdCirlce_Stage1_StrokeEnd =
0;
double thirdCirlce_Stage2_StrokeEnd =
0;
double thirdCirlce_Stage3_StrokeEnd =
0;
double thirdCirlce_Stage4_StrokeEnd =
third_Circle_Stage3_StrokeEnd;
double thirdCirlce_Stage5_StrokeEnd =
third_Circle_Stage4_StrokeEnd;
NSArray<NSNumber*>* thirdCirlce_StrokeEnd_Values =
@[@(thirdCirlce_Stage0_StrokeEnd),
@(thirdCirlce_Stage1_StrokeEnd),
@(thirdCirlce_Stage2_StrokeEnd),
@(thirdCirlce_Stage3_StrokeEnd),
@(thirdCirlce_Stage4_StrokeEnd),
@(thirdCirlce_Stage5_StrokeEnd)];
return thirdCirlce_StrokeEnd_Values;
}
- (NSArray<NSNumber*>*)create_Third_Cirlce_StrokeStart_Values {
double thirdCirlce_Stage0_StrokeStart =
0;
double thirdCirlce_Stage1_StrokeStart =
0;
double thirdCirlce_Stage2_StrokeStart =
0;
double thirdCirlce_Stage3_StrokeStart =
0;
double thirdCirlce_Stage4_StrokeStart =
third_Circle_Stage3_StrokeStart;
double thirdCirlce_Stage5_StrokeStart =
third_Circle_Stage4_StrokeStart;
NSArray<NSNumber*>* thirdCirlce_StrokeEnd_Values =
@[@(thirdCirlce_Stage0_StrokeStart),
@(thirdCirlce_Stage1_StrokeStart),
@(thirdCirlce_Stage2_StrokeStart),
@(thirdCirlce_Stage3_StrokeStart),
@(thirdCirlce_Stage4_StrokeStart),
@(thirdCirlce_Stage5_StrokeStart)];
return thirdCirlce_StrokeEnd_Values;
}
@end
//
// ZZCenterRotateView.h
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "ZZCircleView.h"
typedef void(^firstBallDidRestoreCallBack)(void);
@interface ZZCenterRotateView :
UIView
/**
* 第一个点
*/
@property(nonatomic,strong)
ZZCircleView *firstDot;
/**
* 第二个点
*/
@property(nonatomic,strong)
ZZCircleView *secondDot;
/**
* 第三个点
*/
@property(nonatomic,strong)
ZZCircleView *thirdDot;
/**
* 执行完后回调的block
*/
@property(nonatomic,copy)
firstBallDidRestoreCallBack dotAniationFinishHandler;
/**
* 旋转动画
*/
- (void)rotateAnimation;
/**
* 移除动画
*/
- (void)removeAnimations;
@end
//
// ZZCenterRotateView.m
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZCenterRotateView.h"
#import "ZZLoaderView.h"
@implementation ZZCenterRotateView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super
initWithFrame:frame]) {
[self
setUpDotViews];
}
return
self;
}
- (void)setUpDotViews {
self.firstDot = [ZZCircleView
layer];
self.secondDot = [ZZCircleView
layer];
self.thirdDot = [ZZCircleView
layer];
[self.layer
addSublayer:_firstDot];
[self.layer
addSublayer:_secondDot];
[self.layer
addSublayer:_thirdDot];
CGFloat dotWidth =
self.frame.size.width *
3 / 4 /
2;
CGRect firstDotFrame =
CGRectMake(0,
0, dotWidth, dotWidth);
CGRect secondDotFrame =
CGRectMake(0,
self.frame.size.height-dotWidth,
dotWidth, dotWidth);
CGRect thirdDotFrame =
CGRectMake(self.frame.size.width-dotWidth,
secondDotFrame.origin.y, dotWidth, dotWidth);
self.firstDot.frame = firstDotFrame;
self.secondDot.frame = secondDotFrame;
self.thirdDot.frame = thirdDotFrame;
}
- (void)rotateAnimation {
CABasicAnimation *rotateAnimation = [CABasicAnimation
animationWithKeyPath:@"transform.rotation.z"];
rotateAnimation.fromValue =
@(0.0);
rotateAnimation.toValue =
@(M_PI/2);
rotateAnimation.duration =
ZZRotateAnimationTime;
rotateAnimation.fillMode =
kCAFillModeForwards;
rotateAnimation.removedOnCompletion =
false;
rotateAnimation.delegate =
self;
[rotateAnimation setValue:@"rotateAnimation"
forKey:@"animationName"];
[self.layer
addAnimation:rotateAnimation
forKey:nil];
}
- (void)removeAnimations {
[self.layer
removeAllAnimations];
[[self
firstDot]
removeAllAnimations];
}
- (void)firstDotMoveAnimation {
CGFloat endX =
self.frame.size.width
- self.firstDot.frame.size.width+self.firstDot.frame.size.width/2;
CABasicAnimation *moveAnimation = [CABasicAnimation
animationWithKeyPath:@"position.x"];
moveAnimation.toValue = [[NSNumber
alloc] initWithFloat:endX];
moveAnimation.fromValue =
@(self.firstDot.frame.size.width/2);
moveAnimation.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseIn];
// moveAnimation.fillMode = kCAFillModeForwards;
moveAnimation.duration =
ZZFirstDotMoveAnimationTime;
// moveAnimation.repeatCount = 1000;
// moveAnimation.removedOnCompletion = false;
// [self.firstDot addAnimation:moveAnimation forKey:@"moveAnimation"];
CABasicAnimation *changeAnimation = [CABasicAnimation
animationWithKeyPath:@"factor"];
changeAnimation.toValue =
@(1);
changeAnimation.fromValue =
@(0);
changeAnimation.fillMode =
kCAFillModeForwards;
changeAnimation.duration =
ZZFirstDotMoveAnimationTime;
// changeAnimation.delegate = self ;
// changeAnimation.repeatCount = 1;
// changeAnimation.removedOnCompletion = false;
// [self.firstDot addAnimation:changeAnimation forKey:@"changeAnimation"];
CAAnimationGroup *group = [CAAnimationGroup
animation];
group.animations =
@[moveAnimation,changeAnimation];
group.duration =
ZZFirstDotMoveAnimationTime;
group.removedOnCompletion =
false;
group.fillMode =
kCAFillModeForwards;
group.delegate =
self;
group.beginTime = [self.firstDot
convertTime:CACurrentMediaTime()
toLayer:nil] +
0.1;
[group setValue:@"firstDotGroup"
forKey:@"animationName"];
[self.firstDot
addAnimation:group
forKey:@"firstDotGroup"];
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
NSString *animationName = [anim
valueForKey:@"animationName"];
if ([animationName
isEqualToString:@"rotateAnimation"] ) {
[self
firstDotMoveAnimation];
}
else
if ([animationName isEqualToString:@"firstDotGroup"] ) {
self.firstDot.factor =
1;
self.firstDot.frame =
CGRectMake(self.frame.size.width
- self.firstDot.frame.size.width,
self.firstDot.frame.origin.y,
self.firstDot.frame.size.width,
self.firstDot.frame.size.height);
[self
firstDotRestoreAnimation];
} else
if ([animationName
isEqualToString:@"restoreAnimation"] ) {
[self.layer
removeAllAnimations];
[self.firstDot
removeAllAnimations];
self.firstDot.factor =
0;
[self
restoreFirstDotPosition];
__weak
typeof(self) weakSelf =
self ;
dispatch_time_t delay =
dispatch_time(DISPATCH_TIME_NOW,
NSEC_PER_MSEC *200);
dispatch_after(delay,
dispatch_get_main_queue(), ^{
if(weakSelf !=
nil) {
weakSelf.dotAniationFinishHandler();
}
});
}
}
-(void)firstDotRestoreAnimation {
[self.firstDot
removeAnimationForKey:@"firstDotGroup"];
NSMutableArray *values = [self
springAnimationValues:@(1)
toValue:@(0)
usingSpringWithDamping:4
initialSpringVelocity:10
duration:ZZFirstDotRestoreAnimationTime];
CAKeyframeAnimation *restoreAnimation = [CAKeyframeAnimation
animationWithKeyPath:@"factor"];
restoreAnimation.values = values;
restoreAnimation.duration =
ZZFirstDotRestoreAnimationTime;
restoreAnimation.fillMode =
kCAFillModeForwards;
restoreAnimation.removedOnCompletion =
false;
restoreAnimation.delegate =
self ;
[restoreAnimation setValue:@"restoreAnimation"
forKey:@"animationName"];
[self.firstDot
addAnimation:restoreAnimation
forKey:@"restoreAnimation"];
}
- (void)restoreFirstDotPosition {
[CATransaction
begin];
[CATransaction
setDisableActions:YES];
self.firstDot.frame =
CGRectMake(0,
self.firstDot.frame.origin.y,
self.firstDot.frame.size.width,
self.firstDot.frame.size.height);
[CATransaction
commit];
}
- (NSMutableArray *)springAnimationValues:(id)fromValue
toValue:(id)toValue
usingSpringWithDamping:(CGFloat)damping
initialSpringVelocity:(CGFloat)velocity
duration:(CGFloat)duration {
// 60个关键帧
NSInteger numOfFrames = duration *
60;
NSMutableArray *values = [NSMutableArray
arrayWithCapacity:numOfFrames];
for (NSInteger i =
0; i < numOfFrames; i++) {
[values addObject:@(0.0)];
}
//差值
CGFloat diff = [toValue
floatValue] - [fromValue
floatValue];
for (NSInteger frame =
0; frame < numOfFrames; frame++) {
CGFloat x = (CGFloat)frame / (CGFloat)numOfFrames;
CGFloat value = [toValue
floatValue] -
diff * (pow(M_E, -damping * x) *
cos(velocity * x));
// y = 1-e^{-5x} * cos(30x)
values[frame] = @(value);
}
return values;
}
@end
//
// ZZProgressHUD.h
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, ZZProgressHUDBackgroundType) {
ZZProgressHUDBackgroundTypeNone,
ZZProgressHUDBackgroundTypeDim,
ZZProgressHUDBackgroundTypeBlur,
};
@interface ZZProgressHUD :
UIView
@property (nonatomic,
assign)
ZZProgressHUDBackgroundType backgroundType;
+ (ZZProgressHUD *)hudForView:(UIView *)view;
+ (ZZProgressHUD *)sharedHUD;
- (void)show:(BOOL)animated;
- (void)hide:(BOOL)animated;
+ (void)showSharedHUD:(BOOL)animated withType:(ZZProgressHUDBackgroundType)type;
+ (void)hideSharedHUD:(BOOL)animated;
@end
//
// ZZProgressHUD.m
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZProgressHUD.h"
#import "ZZLoaderView.h"
@interface
ZZProgressHUD()
@property (nonatomic,
strong) UIVisualEffectView *blurView;
@property (nonatomic,
strong) ZZLoaderView *indecatorView;
@end
@implementation ZZProgressHUD
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super
initWithFrame:frame]) {
self.alpha =
0;
[self
setupViewsWith:ZZProgressHUDBackgroundTypeNone];
}
return
self;
}
+ (ZZProgressHUD *)hudForView:(UIView *)view {
ZZProgressHUD *hud = [[ZZProgressHUD
alloc]
initWithFrame:view.frame];
[view addSubview:hud];
return hud;
}
+ (ZZProgressHUD *)sharedHUD{
static
ZZProgressHUD * sharedInstance;
static
dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[ZZProgressHUD
alloc] initWithFrame:CGRectMake(0,
0,[UIScreen
mainScreen].bounds.size.width,
[UIScreen mainScreen].bounds.size.height)];
});
return sharedInstance;
}
- (void)setBackgroundType:(ZZProgressHUDBackgroundType)backgroundType {
_backgroundType = backgroundType;
switch (backgroundType) {
case
ZZProgressHUDBackgroundTypeNone:
self.backgroundColor = [UIColor
clearColor];
_blurView.hidden =
true;
break;
case
ZZProgressHUDBackgroundTypeDim:
self.backgroundColor =
ZZRGBA(0,
0, 0,
0.6);
_blurView.hidden =
true;
break;
case
ZZProgressHUDBackgroundTypeBlur:
self.blurView.hidden =
false;
self.backgroundColor = [UIColor
clearColor];
break;
default:
break;
}
}
- (void)setupViewsWith:(ZZProgressHUDBackgroundType)type {
self.indecatorView = [[ZZLoaderView
alloc] initWithFrame:CGRectMake(0,
0, ZZCircleRadius*2+30,
ZZCircleRadius*2+30)];
_indecatorView.center =
self.center;
_indecatorView.layer.cornerRadius =
5;
_indecatorView.layer.masksToBounds =
true;
_indecatorView.backgroundColor =
ZZRGBA(81,
88, 128,
0.8);
self.blurView = [[UIVisualEffectView
alloc]
initWithFrame:self.frame];
_blurView.effect = [UIBlurEffect
effectWithStyle:UIBlurEffectStyleLight];
[self
addSubview:self.blurView];
switch (type) {
case
ZZProgressHUDBackgroundTypeNone:
_blurView.hidden =
true;
break;
case
ZZProgressHUDBackgroundTypeDim:
self.backgroundColor =
ZZRGBA(0,
0, 0,
0.6);
_blurView.hidden =
true;
break;
case
ZZProgressHUDBackgroundTypeBlur:
break;
default:
break;
}
[self
addSubview:_indecatorView];
}
- (void)show:(BOOL)animated {
NSAssert(self.superview,
@"ZZFundHud should have a superview");
if(animated) {
[UIView
animateWithDuration:0.2
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.alpha =
1;
} completion:^(BOOL completed){
}];
} else {
self.alpha =
1;
}
}
- (void)hide:(BOOL)animated {
if (animated) {
[UIView
animateWithDuration:0.2
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.alpha =
0;
} completion:^(BOOL completed){
[self
removeFromSuperview];
[self.indecatorView
stopLoading];
}];
} else {
self.alpha =
0;
[self
removeFromSuperview];
[self.indecatorView
stopLoading];
}
}
+ (void)showSharedHUD:(BOOL)animated withType:(ZZProgressHUDBackgroundType)type
{
UIView *window = [UIApplication
sharedApplication].windows.lastObject;
ZZProgressHUD *sharedHUD = [ZZProgressHUD
sharedHUD];
sharedHUD.backgroundType = type;
[window addSubview:sharedHUD];
[sharedHUD show:animated];
}
+ (void)hideSharedHUD:(BOOL)animated {
[[ZZProgressHUD
sharedHUD] hide:animated];
}
@end
//
// ViewController.h
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ViewController :
UIViewController
@end
//
// ViewController.m
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ViewController.h"
#import "ZZProgressHUD.h"
@interface
ViewController ()
- (IBAction)showDimHUD:(UIButton *)button;
- (IBAction)showDefaultHUD:(UIButton *)button;
- (IBAction)showBlurHUD:(UIButton *)button;
- (IBAction)showSharedHUD:(UIButton *)button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super
viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super
didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)showDimHUD:(UIButton *)button {
ZZProgressHUD *hud = [ZZProgressHUD
hudForView:self.view];
hud.backgroundType =
ZZProgressHUDBackgroundTypeDim;
[hud show:YES];
[self
performHideAfterSecond:5
hud:hud];
}
- (IBAction)showDefaultHUD:(UIButton *)button {
ZZProgressHUD *hud = [ZZProgressHUD
hudForView:self.view];
hud.backgroundType =
ZZProgressHUDBackgroundTypeNone;
[hud show:YES];
[self
performHideAfterSecond:5
hud:hud];
}
- (IBAction)showBlurHUD:(UIButton *)button {
ZZProgressHUD *hud = [ZZProgressHUD
hudForView:self.view];
hud.backgroundType =
ZZProgressHUDBackgroundTypeBlur;
[hud show:YES];
[self
performHideAfterSecond:5
hud:hud];
}
- (IBAction)showSharedHUD:(UIButton *)button {
[ZZProgressHUD
showSharedHUD:YES
withType:ZZProgressHUDBackgroundTypeBlur];
[self
performHideAfterSecond:5
hud:[ZZProgressHUD
sharedHUD]];
}
- (void)performHideAfterSecond:(double)sec hud:(ZZProgressHUD *)hud {
uint64_t msc = sec *
1000;
dispatch_time_t delay =
dispatch_time(DISPATCH_TIME_NOW,
NSEC_PER_MSEC * msc);
dispatch_after(delay,
dispatch_get_main_queue(), ^{
[hud hide:true];
});
}
@end
//
// ZZCircleView.h
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
@interface ZZCircleView :
CALayer
@property (nonatomic,
assign) CGFloat factor;
@end
//
// ZZCircleView.m
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZCircleView.h"
@interface
ZZCircleView()
@property (nonatomic,
assign) CGSize circleRectSize;
@end
@implementation ZZCircleView
#pragma mark - 构造方法初始化
- (instancetype)init
{
if (self = [super
init]) {
self.factor =
0;
self.masksToBounds =
NO;
self.contentsScale = [UIScreen
mainScreen].scale;
}
return
self;
}
#pragma mark - 重写frame方法
- (void)setFrame:(CGRect)frame
{
[super
setFrame:frame];
self.circleRectSize = frame.size;
[self
setNeedsDisplay];
}
#pragma mark - 根据key值来调用super的方法
+ (BOOL)needsDisplayForKey:(NSString *)key
{
if ([key
isEqualToString:@"factor"]) {
return
YES;
}
return [super
needsDisplayForKey:key];
}
#pragma mark - 在上下文中绘制
- (void)drawInContext:(CGContextRef)ctx
{
// width + 1/6*width * 2 = S
CGFloat percent = (1+1.0/6*2);
CGSize dotSize =
CGSizeMake(self.frame.size.width/percent,
self.frame.size.height/percent);
//NSLog(@"%f",_factor);
CGFloat offset = dotSize.width /
3.6;
CGFloat moveDistance = dotSize.width *
1/6 *
_factor;
CGPoint center =
CGPointMake(self.frame.size.width/2,
self.frame.size.height/2);
CGPoint pointA =
CGPointMake(center.x,center.y-dotSize.height/2+moveDistance);
CGPoint pointB =
CGPointMake(center.x+dotSize.width/2+moveDistance,
center.y);
CGPoint pointC =
CGPointMake(center.x, center.y+dotSize.height/2-moveDistance);
CGPoint pointD =
CGPointMake(center.x-dotSize.width/2-moveDistance,
center.y);
CGPoint c1 =
CGPointMake(pointA.x+offset,pointA.y);
CGPoint c2 =
CGPointMake(pointB.x, pointB.y-offset);
CGPoint c3 =
CGPointMake(pointB.x, pointB.y+offset);
CGPoint c4 =
CGPointMake(pointC.x+offset,pointC.y);
CGPoint c5 =
CGPointMake(pointC.x-offset, pointC.y);
CGPoint c6 =
CGPointMake(pointD.x, pointD.y+offset);
CGPoint c7 =
CGPointMake(pointD.x, pointD.y-offset);
CGPoint c8 =
CGPointMake(pointA.x-offset, pointA.y);
UIBezierPath *path = [UIBezierPath
bezierPath];
[path moveToPoint:pointA];
[path addCurveToPoint:pointB
controlPoint1:c1
controlPoint2:c2];
[path addCurveToPoint:pointC
controlPoint1:c3
controlPoint2:c4];
[path addCurveToPoint:pointD
controlPoint1:c5
controlPoint2:c6];
[path addCurveToPoint:pointA
controlPoint1:c7
controlPoint2:c8];
[path closePath];
CGContextAddPath(ctx, path.CGPath);
CGContextSetFillColorWithColor(ctx,[UIColor
whiteColor].CGColor);
CGContextFillPath(ctx);
}
@end
//
// ZZLoaderView.h
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#define ZZCircleStrokWidth 10
#define Radians(x) (M_PI * (x) / 180.0)
#define InsetRadians_between_line M_PI / 6
#define ZZLineAnimationTime 0.8
#define ZZRotateAnimationTime (ZZLineAnimationTime * 4 /
10)
#define ZZFirstDotMoveAnimationTime (ZZLineAnimationTime *
5 / 10)
#define ZZFirstDotRestoreAnimationTime (ZZLineAnimationTime *
6 / 10)
#define ZZCircleRadius 70
#define ZZFirstCircleLength (4 * M_PI + (M_PI/2 - M_PI/12))
#define ZZSecondCircleLength (4 * M_PI +(M_PI/2 - M_PI/12))
#define ZZThirdCircleLength (M_PI*5/4 + M_PI/3)
#define ZZFirstCircelStartAngle (-M_PI/2)
#define ZZFirstCircelEndAngle (4*M_PI - M_PI/12)
#define ZZSecondCircelStartAngle (-M_PI/2)
#define ZZSecondCircelEndAngle (4*M_PI - M_PI/12)
#define ZZThirdCircelStartAngle (-M_PI/3)
#define ZZthirdCircelEndAngle (M_PI+M_PI/5)
#define ZZRGBA(r,g,b,a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f
alpha:a]
#define ZZStrokeWidth 12
#import <UIKit/UIKit.h>
@interface ZZLoaderView :
UIView
- (void)startLoading;
- (void)stopLoading;
@end
//
// ZZLoaderView.m
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZLoaderView.h"
#import "ZZCenterRotateView.h"
@interface
ZZLoaderView() {
double first_Circle_Stage1_StrokeEnd;
double first_Circle_Stage2_StrokeEnd;
double first_Circle_Stage3_StrokeEnd;
double first_Circle_Stage4_StrokeEnd;
double first_Circle_Stage1_StrokeStart;
double first_Circle_Stage2_StrokeStart;
double first_Circle_Stage3_StrokeStart;
double first_Circle_Stage4_StrokeStart;
double second_Circle_Stage1_StrokeEnd;
double second_Circle_Stage2_StrokeEnd;
double second_Circle_Stage3_StrokeEnd;
double second_Circle_Stage4_StrokeEnd;
double second_Circle_Stage1_StrokeStart;
double second_Circle_Stage2_StrokeStart;
double second_Circle_Stage3_StrokeStart;
double second_Circle_Stage4_StrokeStart;
double third_Circle_Stage3_StrokeEnd;
double third_Circle_Stage4_StrokeEnd;
double third_Circle_Stage3_StrokeStart;
double third_Circle_Stage4_StrokeStart;
}
@property(nonatomic,strong)
ZZCenterRotateView *rotateView;
@property(nonatomic,strong)
CAAnimationGroup *firstCircleAnimationGroup;
@property(nonatomic,strong)
CAAnimationGroup *secondCircleAnimationGroup;
@end
@implementation ZZLoaderView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super
initWithFrame:frame]) {
[self
setUpStageValues];
[self
setUpRotateView];
[self
startLoading];
self.backgroundColor = [UIColor
clearColor];
}
return
self;
}
- (void)startLoading {
[self
removeLines];
[self
creatFirstThreePathLayer];
[self
creatSecondThreePathLayer];
}
- (void)stopLoading {
[self.rotateView
removeAnimations];
[self
removeLines];
/* NSArray *sublayers = [self.layer sublayers];
for(CALayer *layer in sublayers) {
[layer removeAllAnimations];
[layer removeFromSuperlayer];
}*/
}
- (void)removeLines {
NSArray *sublayers = [self.layer
sublayers];
NSInteger count = sublayers.count;
for(NSInteger i =
0;i < count;) {
id layer = sublayers[i];
if ([layer
isKindOfClass:[CAShapeLayer
class]]) {
[layer removeAllAnimations];
[layer removeFromSuperlayer];
count -= 1;
} else {
i++;
}
}
}
- (void)setUpRotateView {
CGFloat rotateViewWidth =
ZZCircleRadius +
10;
CGFloat rotateViewHeight = rotateViewWidth;
CGFloat rotateX = (self.frame.size.width
- rotateViewWidth)/2;
CGFloat rotateY = (self.frame.size.height
- rotateViewHeight)/2;
self.rotateView = [[ZZCenterRotateView
alloc] initWithFrame:CGRectMake(rotateX, rotateY, rotateViewWidth, rotateViewHeight)];
__weak
typeof(self) weakSelf =
self ;
self.rotateView.dotAniationFinishHandler
= ^{
[weakSelf startLoading];
};
[self
addSubview:self.rotateView];
}
- (void)setUpStageValues {
double s1 =
ZZFirstCircleLength;
double s2 =
ZZSecondCircleLength;
double s3 =
ZZThirdCircleLength;
first_Circle_Stage1_StrokeEnd = (M_PI+M_PI/8)/s1;
first_Circle_Stage2_StrokeEnd = (4*M_PI-M_PI*1/3)/s1;
first_Circle_Stage3_StrokeEnd = (4*M_PI+M_PI/6)/s1;
first_Circle_Stage4_StrokeEnd =
1;
first_Circle_Stage1_StrokeStart = (M_PI/2-M_PI/6)/s1;
first_Circle_Stage2_StrokeStart = (2*M_PI
+ M_PI/6)/s1;
//同时也是白线起点
first_Circle_Stage3_StrokeStart = (4*M_PI-M_PI/6)/s1;
first_Circle_Stage4_StrokeStart = (s1-M_PI/30)/s1;//1;
second_Circle_Stage1_StrokeEnd = (M_PI+M_PI/8-M_PI/12)/s2;
second_Circle_Stage2_StrokeEnd = (4*M_PI-M_PI*1/3-M_PI/3)/s2;
second_Circle_Stage3_StrokeEnd = (4*M_PI-M_PI/6)/s2;
second_Circle_Stage4_StrokeEnd = (4 *
M_PI )/s2;
second_Circle_Stage1_StrokeStart = (M_PI/2-M_PI/6)/s2;
second_Circle_Stage2_StrokeStart = (2*M_PI
+ M_PI/6)/s2;;
//同时也是白线起点
second_Circle_Stage3_StrokeStart = (4*M_PI-M_PI/6-M_PI/3)/s2;
second_Circle_Stage4_StrokeStart = (4 *
M_PI-M_PI/30)/s2;//(4
* M_PI )/s2;
third_Circle_Stage3_StrokeEnd = (M_PI*5/4)/s3;
third_Circle_Stage4_StrokeEnd =
1;
third_Circle_Stage3_StrokeStart = (M_PI*5/4-M_PI/3)/s3;
third_Circle_Stage4_StrokeStart = (s3 -
M_PI/30)/s3;//1;
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
NSString *animationName = [anim
valueForKey:@"animationName"];
if ([animationName
isEqualToString:@"firstCircleGroup"]) {
} else
if ([animationName
isEqualToString:@""]) {
}
}
/**
* 毫秒
*
* @param mscDelay 毫秒
*/
- (void)startRotateAfterSeconds:(int) mscDelay {
__weak
typeof(self) weakSelf =
self ;
dispatch_time_t delay =
dispatch_time(DISPATCH_TIME_NOW,
NSEC_PER_MSEC *mscDelay);
dispatch_after(delay,
dispatch_get_main_queue(), ^{
[weakSelf.rotateView
rotateAnimation];
});
}
- (void)creatFirstThreePathLayer {
CAShapeLayer *firstCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:firstCirlce];
CAShapeLayer *secondCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:secondCirlce];
CAShapeLayer *thirdCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:thirdCirlce];
/**
* 绿线
*/
UIBezierPath *firstCirlcePath = [self
creatCirclePathWithRadius:ZZCircleRadius
startAngle:ZZFirstCircelStartAngle
endAngle:ZZFirstCircelEndAngle];
firstCirlce.strokeColor =
ZZRGBA(144,
241, 9,
1).CGColor;
firstCirlce.fillColor = [UIColor
clearColor].CGColor;
firstCirlce.lineWidth =
ZZStrokeWidth;
firstCirlce.contentsScale = [UIScreen
mainScreen].scale;
firstCirlce.lineCap =
kCALineCapRound;
firstCirlce.path = firstCirlcePath.CGPath;
firstCirlce.strokeEnd =
0;
firstCirlce.strokeStart =
0;
NSArray<NSNumber*>* firstCirlce_StrokeEnd_Values = [self
create_Fast_First_Cirlce_StrokeEnd_Values];
NSArray<NSNumber*>* firstCirlceTimes = [self
create_Fast_CirlceTimes];
NSArray<NSNumber*>* firstCirlce_StrokeStart_Values = [self
create_Fast_First_Cirlce_StrokeStart_Values];
CAKeyframeAnimation *firstCircle_StrokeEnd_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeEnd"];
firstCircle_StrokeEnd_Animation.values = firstCirlce_StrokeEnd_Values;
firstCircle_StrokeEnd_Animation.keyTimes = firstCirlceTimes;
firstCircle_StrokeEnd_Animation.duration =
ZZLineAnimationTime;
CAKeyframeAnimation *firstCircle_StrokeStart_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeStart"];
firstCircle_StrokeStart_Animation.values = firstCirlce_StrokeStart_Values;
firstCircle_StrokeStart_Animation.keyTimes = firstCirlceTimes;
firstCircle_StrokeStart_Animation.duration =
ZZLineAnimationTime;
CAAnimationGroup *firstCircleGroup = [CAAnimationGroup
animation];
firstCircleGroup.animations =
@[firstCircle_StrokeStart_Animation,firstCircle_StrokeEnd_Animation];
firstCircleGroup.duration =
ZZLineAnimationTime;
firstCircleGroup.delegate =
self ;
// firstCircleGroup.removedOnCompletion = true;
// firstCircleGroup.repeatCount = MAXFLOAT;
[firstCircleGroup setValue:@"firstCircleGroup"
forKey:@"animationName"];
[firstCirlce addAnimation:firstCircleGroup
forKey:nil];
/**
* 黄线
*/
UIBezierPath *secondCirlcePath = [self
creatCirclePathWithRadius:ZZCircleRadius
startAngle:ZZSecondCircelStartAngle
endAngle:ZZSecondCircelEndAngle];
secondCirlce.strokeColor =
ZZRGBA(253,
184, 9,
1).CGColor;
secondCirlce.fillColor = [UIColor
clearColor].CGColor;
secondCirlce.lineWidth =
ZZStrokeWidth;
secondCirlce.contentsScale = [UIScreen
mainScreen].scale;
secondCirlce.lineCap =
kCALineCapRound;
secondCirlce.path = secondCirlcePath.CGPath;
secondCirlce.strokeEnd =
0;
secondCirlce.strokeStart =
0;
NSArray<NSNumber*>* secondCirlce_StrokeEnd_Values = [self
create_Fast_Second_Cirlce_StrokeEnd_Values];
NSArray<NSNumber*> *secondCirlce_StrokeStart_Values = [self
create_Fast_Second_Cirlce_StrokeStart_Values];
NSArray<NSNumber*> *secondCirlceTimes = firstCirlceTimes.copy;
CAKeyframeAnimation *secondCircle_StrokeEnd_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeEnd"];
secondCircle_StrokeEnd_Animation.values = secondCirlce_StrokeEnd_Values;
secondCircle_StrokeEnd_Animation.keyTimes = secondCirlceTimes;
secondCircle_StrokeEnd_Animation.duration =
ZZLineAnimationTime;
CAKeyframeAnimation *secondCircle_StrokeStart_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeStart"];
secondCircle_StrokeStart_Animation.values = secondCirlce_StrokeStart_Values;
secondCircle_StrokeStart_Animation.keyTimes = secondCirlceTimes;
secondCircle_StrokeStart_Animation.duration =
ZZLineAnimationTime;
CAAnimationGroup *secondCircleGroup = [CAAnimationGroup
animation];
secondCircleGroup.animations =
@[secondCircle_StrokeEnd_Animation,secondCircle_StrokeStart_Animation];
secondCircleGroup.duration =
ZZLineAnimationTime;
secondCircleGroup.delegate =
self ;
// secondCircleGroup.removedOnCompletion = true;
// secondCircleGroup.repeatCount = MAXFLOAT;
// [secondCircleGroup setValue:@"firstCircleGroup" forKey:@"animationName"];
[secondCirlce addAnimation:secondCircleGroup
forKey:nil];
[self
startRotateAfterSeconds:ZZLineAnimationTime *
0.2*1000];
}
- (void) creatSecondThreePathLayer {
CAShapeLayer *firstCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:firstCirlce];
CAShapeLayer *secondCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:secondCirlce];
CAShapeLayer *thirdCirlce = [CAShapeLayer
layer];
[self.layer
addSublayer:thirdCirlce];
/**
* 绿线
*/
UIBezierPath *firstCirlcePath = [self
creatCirclePathWithRadius:ZZCircleRadius
startAngle:ZZFirstCircelStartAngle
endAngle:ZZFirstCircelEndAngle];
firstCirlce.strokeColor =
ZZRGBA(144,
241, 9,
1).CGColor;
firstCirlce.fillColor = [UIColor
clearColor].CGColor;
firstCirlce.lineWidth =
ZZStrokeWidth;
firstCirlce.contentsScale = [UIScreen
mainScreen].scale;
firstCirlce.lineCap =
kCALineCapRound;
firstCirlce.path = firstCirlcePath.CGPath;
firstCirlce.strokeEnd =
0;
firstCirlce.strokeStart =
0;
NSArray<NSNumber*>* firstCirlce_StrokeEnd_Values = [self
create_Slow_First_Cirlce_StrokeEnd_Values];
NSArray<NSNumber*>* firstCirlceTimes = [self
create_Slow_CirlceTimes];
NSArray<NSNumber*>* firstCirlce_StrokeStart_Values = [self
create_Slow_First_Cirlce_StrokeStart_Values];
CAKeyframeAnimation *firstCircle_StrokeEnd_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeEnd"];
firstCircle_StrokeEnd_Animation.values = firstCirlce_StrokeEnd_Values;
firstCircle_StrokeEnd_Animation.keyTimes = firstCirlceTimes;
firstCircle_StrokeEnd_Animation.duration =
ZZLineAnimationTime;
CAKeyframeAnimation *firstCircle_StrokeStart_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeStart"];
firstCircle_StrokeStart_Animation.values = firstCirlce_StrokeStart_Values;
firstCircle_StrokeStart_Animation.keyTimes = firstCirlceTimes;
firstCircle_StrokeStart_Animation.duration =
ZZLineAnimationTime;
CAAnimationGroup *firstCircleGroup = [CAAnimationGroup
animation];
firstCircleGroup.animations =
@[firstCircle_StrokeStart_Animation,firstCircle_StrokeEnd_Animation];
firstCircleGroup.duration =
ZZLineAnimationTime;
firstCircleGroup.delegate =
self ;
// firstCircleGroup.removedOnCompletion = true;
[firstCircleGroup setValue:@"secondCircleGroup"
forKey:@"animationName"];
// firstCircleGroup.repeatCount = MAXFLOAT;
[firstCirlce addAnimation:firstCircleGroup
forKey:nil];
/**
* 黄线
*/
UIBezierPath *secondCirlcePath = [self
creatCirclePathWithRadius:ZZCircleRadius
startAngle:ZZSecondCircelStartAngle
endAngle:ZZSecondCircelEndAngle];
secondCirlce.strokeColor =
ZZRGBA(253,
184, 9,
1).CGColor;
secondCirlce.fillColor = [UIColor
clearColor].CGColor;
secondCirlce.lineWidth =
ZZStrokeWidth;
secondCirlce.contentsScale = [UIScreen
mainScreen].scale;
secondCirlce.lineCap =
kCALineCapRound;
secondCirlce.path = secondCirlcePath.CGPath;
secondCirlce.strokeEnd =
0;
secondCirlce.strokeStart =
0;
NSArray<NSNumber*>* secondCirlce_StrokeEnd_Values = [self
create_Slow_Second_Cirlce_StrokeEnd_Values];
NSArray<NSNumber*> *secondCirlce_StrokeStart_Values = [self
create_Slow_Second_Cirlce_StrokeStart_Values];
NSArray<NSNumber*> *secondCirlceTimes = firstCirlceTimes.copy;
CAKeyframeAnimation *secondCircle_StrokeEnd_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeEnd"];
secondCircle_StrokeEnd_Animation.values = secondCirlce_StrokeEnd_Values;
secondCircle_StrokeEnd_Animation.keyTimes = secondCirlceTimes;
secondCircle_StrokeEnd_Animation.duration =
ZZLineAnimationTime;
CAKeyframeAnimation *secondCircle_StrokeStart_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeStart"];
secondCircle_StrokeStart_Animation.values = secondCirlce_StrokeStart_Values;
secondCircle_StrokeStart_Animation.keyTimes = secondCirlceTimes;
secondCircle_StrokeStart_Animation.duration =
ZZLineAnimationTime;
CAAnimationGroup *secondCircleGroup = [CAAnimationGroup
animation];
secondCircleGroup.animations =
@[secondCircle_StrokeEnd_Animation,secondCircle_StrokeStart_Animation];
secondCircleGroup.duration =
ZZLineAnimationTime;
secondCircleGroup.delegate =
self ;
// secondCircleGroup.removedOnCompletion = true;
//secondCircleGroup.repeatCount = MAXFLOAT;
//[secondCircleGroup setValue:@"firstCircleGroup" forKey:@"animationName"];
[secondCirlce addAnimation:secondCircleGroup
forKey:nil];
/**
* 白线
*/
UIBezierPath *thirdCirlcePath = [self
creatCirclePathWithRadius:ZZCircleRadius
startAngle:ZZThirdCircelStartAngle
endAngle:ZZthirdCircelEndAngle];
thirdCirlce.strokeColor = [[UIColor
whiteColor] CGColor];
thirdCirlce.fillColor = [UIColor
clearColor].CGColor;
thirdCirlce.lineWidth =
ZZStrokeWidth;
thirdCirlce.contentsScale = [UIScreen
mainScreen].scale;
thirdCirlce.lineCap =
kCALineCapRound;
thirdCirlce.path = thirdCirlcePath.CGPath;
thirdCirlce.strokeEnd =
0;
thirdCirlce.strokeStart =
0;
NSArray<NSNumber*>* thirdCirlce_StrokeEnd_Values = [self
create_Third_Cirlce_StrokeEnd_Values];
NSArray<NSNumber*> *thirdCirlce_StrokeStart_Values = [self
create_Third_Cirlce_StrokeStart_Values];
NSArray<NSNumber*> *thirdCirlceTimes = firstCirlceTimes.copy;
CAKeyframeAnimation *thirdCircle_StrokeEnd_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeEnd"];
thirdCircle_StrokeEnd_Animation.values = thirdCirlce_StrokeEnd_Values;
thirdCircle_StrokeEnd_Animation.keyTimes = thirdCirlceTimes;
thirdCircle_StrokeEnd_Animation.duration =
ZZLineAnimationTime;
CAKeyframeAnimation *thirdCircle_StrokeStart_Animation = [CAKeyframeAnimation
animationWithKeyPath:@"strokeStart"];
thirdCircle_StrokeStart_Animation.values = thirdCirlce_StrokeStart_Values;
thirdCircle_StrokeStart_Animation.keyTimes = thirdCirlceTimes;
thirdCircle_StrokeStart_Animation.duration =
ZZLineAnimationTime;
CAAnimationGroup *thirdCircleGroup = [CAAnimationGroup
animation];
thirdCircleGroup.animations =
@[thirdCircle_StrokeEnd_Animation,thirdCircle_StrokeStart_Animation];
thirdCircleGroup.duration =
ZZLineAnimationTime;
thirdCircleGroup.delegate =
self ;
// thirdCircleGroup.removedOnCompletion = true;
// thirdCircleGroup.repeatCount = MAXFLOAT;
// [thirdCircleGroup setValue:@"thirdCircleGroup" forKey:@"animationName"];
[thirdCirlce addAnimation:thirdCircleGroup
forKey:nil];
}
- (UIBezierPath*)creatCirclePathWithRadius: (double)radius startAngle:(double)startAngle
endAngle:(double)endAngle {
UIBezierPath *path ;
path = [UIBezierPath
bezierPathWithArcCenter:CGPointMake(self.frame.size.width/2,
self.frame.size.height/2)
radius:radius startAngle:startAngle
endAngle:endAngle
clockwise:YES];
return path;
}
#pragma mark 第一个圈圈(快和慢)
- (NSArray<NSNumber*>*)create_Fast_First_Cirlce_StrokeEnd_Values {
double firstCirlce_Stage0_StrokeEnd =
0;
double firstCirlce_Stage1_StrokeEnd =
first_Circle_Stage1_StrokeEnd;
double firstCirlce_Stage2_StrokeEnd =
first_Circle_Stage2_StrokeEnd;
double firstCirlce_Stage3_StrokeEnd =
first_Circle_Stage3_StrokeEnd;
double firstCirlce_Stage4_StrokeEnd =
first_Circle_Stage4_StrokeEnd;
NSArray<NSNumber*>* firstCirlce_StrokeEnd_Values =
@[@(firstCirlce_Stage0_StrokeEnd),
@(firstCirlce_Stage1_StrokeEnd),
@(firstCirlce_Stage2_StrokeEnd),
@(firstCirlce_Stage3_StrokeEnd),
@(firstCirlce_Stage4_StrokeEnd)];
return firstCirlce_StrokeEnd_Values;
}
- (NSArray<NSNumber*>*)create_Fast_First_Cirlce_StrokeStart_Values {
double firstCirlce_Stage0_StrokeStart =
0;
double firstCirlce_Stage1_StrokeStart =
first_Circle_Stage1_StrokeStart;
double firstCirlce_Stage2_StrokeStart =
first_Circle_Stage2_StrokeStart;
double firstCirlce_Stage3_StrokeStart =
first_Circle_Stage3_StrokeStart;
double firstCirlce_Stage4_StrokeStart =
first_Circle_Stage4_StrokeStart;
NSArray<NSNumber*>* firstCirlce_StrokeStart_Values =
@[@(firstCirlce_Stage0_StrokeStart),
@(firstCirlce_Stage1_StrokeStart),
@(firstCirlce_Stage2_StrokeStart),
@(firstCirlce_Stage3_StrokeStart),
@(firstCirlce_Stage4_StrokeStart)];
return firstCirlce_StrokeStart_Values;
}
- (NSArray<NSNumber*>*)create_Fast_CirlceTimes {
double firstCirlce_Stage0_Stroke_Time =
0.0/10;
double firstCirlce_Stage1_Stroke_Time =
2.0/10;
double firstCirlce_Stage2_Stroke_Time = (6.0)/10;
double firstCirlce_Stage3_Stroke_Time = (8.1)/10;
double firstCirlce_Stage4_Stroke_Time = (10.0)/10;
NSArray<NSNumber*>* firstCirlceTimes =
@[@(firstCirlce_Stage0_Stroke_Time),
@(firstCirlce_Stage1_Stroke_Time),
@(firstCirlce_Stage2_Stroke_Time),
@(firstCirlce_Stage3_Stroke_Time),
@(firstCirlce_Stage4_Stroke_Time)];
return firstCirlceTimes;
}
- (NSArray<NSNumber*>*)create_Slow_First_Cirlce_StrokeEnd_Values {
double firstCirlce_Stage0_StrokeEnd =
0;
double firstCirlce_Stage1_StrokeEnd =
0;
double firstCirlce_Stage2_StrokeEnd =
first_Circle_Stage1_StrokeEnd;
double firstCirlce_Stage3_StrokeEnd =
first_Circle_Stage2_StrokeEnd;
double firstCirlce_Stage4_StrokeEnd =
first_Circle_Stage3_StrokeEnd;
double firstCirlce_Stage5_StrokeEnd =
first_Circle_Stage4_StrokeEnd;
NSArray<NSNumber*>* firstCirlce_StrokeEnd_Values =
@[@(firstCirlce_Stage0_StrokeEnd),
@(firstCirlce_Stage1_StrokeEnd),
@(firstCirlce_Stage2_StrokeEnd),
@(firstCirlce_Stage3_StrokeEnd),
@(firstCirlce_Stage4_StrokeEnd),
@(firstCirlce_Stage5_StrokeEnd)];
return firstCirlce_StrokeEnd_Values;
}
- (NSArray<NSNumber*>*)create_Slow_CirlceTimes {
double firstCirlce_Stage0_Stroke_Time =
0.0/10.0;
double firstCirlce_Stage1_Stroke_Time =
1.0/10;
double firstCirlce_Stage2_Stroke_Time = (3.0)/10;
double firstCirlce_Stage3_Stroke_Time = (6.0)/10;
double firstCirlce_Stage4_Stroke_Time = (8.1)/10;
double firstCirlce_Stage5_Stroke_Time = (10.0)/10;
NSArray<NSNumber*>* firstCirlceTimes =
@[@(firstCirlce_Stage0_Stroke_Time),
@(firstCirlce_Stage1_Stroke_Time),
@(firstCirlce_Stage2_Stroke_Time),
@(firstCirlce_Stage3_Stroke_Time),
@(firstCirlce_Stage4_Stroke_Time),
@(firstCirlce_Stage5_Stroke_Time)];
return firstCirlceTimes;
}
- (NSArray<NSNumber*>*)create_Slow_First_Cirlce_StrokeStart_Values {
double firstCirlce_Stage0_StrokeStart =
0;
double firstCirlce_Stage1_StrokeStart =
0;
double firstCirlce_Stage2_StrokeStart =
first_Circle_Stage1_StrokeStart;
double firstCirlce_Stage3_StrokeStart =
first_Circle_Stage2_StrokeStart;
double firstCirlce_Stage4_StrokeStart =
first_Circle_Stage3_StrokeStart;
double firstCirlce_Stage5_StrokeStart =
first_Circle_Stage4_StrokeStart;
NSArray<NSNumber*>* firstCirlce_StrokeStart_Values =
@[@(firstCirlce_Stage0_StrokeStart),
@(firstCirlce_Stage1_StrokeStart),
@(firstCirlce_Stage2_StrokeStart),
@(firstCirlce_Stage3_StrokeStart),
@(firstCirlce_Stage4_StrokeStart),
@(firstCirlce_Stage5_StrokeStart)];
return firstCirlce_StrokeStart_Values;
}
#pragma mark 第二个圈圈(快和慢)
- (NSArray<NSNumber*>*)create_Fast_Second_Cirlce_StrokeEnd_Values {
double secondCirlce_Stage0_StrokeEnd =
0;
double secondCirlce_Stage1_StrokeEnd =
second_Circle_Stage1_StrokeEnd;
double secondCirlce_Stage2_StrokeEnd =
second_Circle_Stage2_StrokeEnd;
double secondCirlce_Stage3_StrokeEnd =
second_Circle_Stage3_StrokeEnd;
double secondCirlce_Stage4_StrokeEnd =
second_Circle_Stage4_StrokeEnd;
NSArray<NSNumber*>* secondCirlce_StrokeEnd_Values =
@[@(secondCirlce_Stage0_StrokeEnd),
@(secondCirlce_Stage1_StrokeEnd),
@(secondCirlce_Stage2_StrokeEnd),
@(secondCirlce_Stage3_StrokeEnd),
@(secondCirlce_Stage4_StrokeEnd)];
return secondCirlce_StrokeEnd_Values;
}
- (NSArray<NSNumber*>*)create_Fast_Second_Cirlce_StrokeStart_Values {
double secondCirlce_Stage0_StrokeStart =
0;
double secondCirlce_Stage1_StrokeStart =
second_Circle_Stage1_StrokeStart;
double secondCirlce_Stage2_StrokeStart =
second_Circle_Stage2_StrokeStart;
double secondCirlce_Stage3_StrokeStart =
second_Circle_Stage3_StrokeStart;
double secondCirlce_Stage4_StrokeStart =
second_Circle_Stage4_StrokeStart;
NSArray<NSNumber*> *secondCirlce_StrokeStart_Values =
@[@(secondCirlce_Stage0_StrokeStart),
@(secondCirlce_Stage1_StrokeStart),
@(secondCirlce_Stage2_StrokeStart),
@(secondCirlce_Stage3_StrokeStart),
@(secondCirlce_Stage4_StrokeStart)];
return secondCirlce_StrokeStart_Values;
}
- (NSArray<NSNumber*>*)create_Slow_Second_Cirlce_StrokeEnd_Values {
double secondCirlce_Stage0_StrokeEnd =
0;
double secondCirlce_Stage1_StrokeEnd =
0;
double secondCirlce_Stage2_StrokeEnd =
second_Circle_Stage1_StrokeEnd;
double secondCirlce_Stage3_StrokeEnd =
second_Circle_Stage2_StrokeEnd;
double secondCirlce_Stage4_StrokeEnd =
second_Circle_Stage3_StrokeEnd;
double secondCirlce_Stage5_StrokeEnd =
second_Circle_Stage4_StrokeEnd;
NSArray<NSNumber*>* secondCirlce_StrokeEnd_Values =
@[@(secondCirlce_Stage0_StrokeEnd),
@(secondCirlce_Stage1_StrokeEnd),
@(secondCirlce_Stage2_StrokeEnd),
@(secondCirlce_Stage3_StrokeEnd),
@(secondCirlce_Stage4_StrokeEnd),
@(secondCirlce_Stage5_StrokeEnd)];
return secondCirlce_StrokeEnd_Values;
}
- (NSArray<NSNumber*>*)create_Slow_Second_Cirlce_StrokeStart_Values {
double secondCirlce_Stage0_StrokeStart =
0;
double secondCirlce_Stage1_StrokeStart =
0;
double secondCirlce_Stage2_StrokeStart =
second_Circle_Stage1_StrokeStart;
double secondCirlce_Stage3_StrokeStart =
second_Circle_Stage2_StrokeStart;
double secondCirlce_Stage4_StrokeStart =
second_Circle_Stage3_StrokeStart;
double secondCirlce_Stage5_StrokeStart =
second_Circle_Stage4_StrokeStart;
NSArray<NSNumber*> *secondCirlce_StrokeStart_Values =
@[@(secondCirlce_Stage0_StrokeStart),
@(secondCirlce_Stage1_StrokeStart),
@(secondCirlce_Stage2_StrokeStart),
@(secondCirlce_Stage3_StrokeStart),
@(secondCirlce_Stage4_StrokeStart),
@(secondCirlce_Stage5_StrokeStart)];
return secondCirlce_StrokeStart_Values;
}
#pragma mark 第三个圈圈(快和慢)
- (NSArray<NSNumber*>*)create_Third_Cirlce_StrokeEnd_Values {
double thirdCirlce_Stage0_StrokeEnd =
0;
double thirdCirlce_Stage1_StrokeEnd =
0;
double thirdCirlce_Stage2_StrokeEnd =
0;
double thirdCirlce_Stage3_StrokeEnd =
0;
double thirdCirlce_Stage4_StrokeEnd =
third_Circle_Stage3_StrokeEnd;
double thirdCirlce_Stage5_StrokeEnd =
third_Circle_Stage4_StrokeEnd;
NSArray<NSNumber*>* thirdCirlce_StrokeEnd_Values =
@[@(thirdCirlce_Stage0_StrokeEnd),
@(thirdCirlce_Stage1_StrokeEnd),
@(thirdCirlce_Stage2_StrokeEnd),
@(thirdCirlce_Stage3_StrokeEnd),
@(thirdCirlce_Stage4_StrokeEnd),
@(thirdCirlce_Stage5_StrokeEnd)];
return thirdCirlce_StrokeEnd_Values;
}
- (NSArray<NSNumber*>*)create_Third_Cirlce_StrokeStart_Values {
double thirdCirlce_Stage0_StrokeStart =
0;
double thirdCirlce_Stage1_StrokeStart =
0;
double thirdCirlce_Stage2_StrokeStart =
0;
double thirdCirlce_Stage3_StrokeStart =
0;
double thirdCirlce_Stage4_StrokeStart =
third_Circle_Stage3_StrokeStart;
double thirdCirlce_Stage5_StrokeStart =
third_Circle_Stage4_StrokeStart;
NSArray<NSNumber*>* thirdCirlce_StrokeEnd_Values =
@[@(thirdCirlce_Stage0_StrokeStart),
@(thirdCirlce_Stage1_StrokeStart),
@(thirdCirlce_Stage2_StrokeStart),
@(thirdCirlce_Stage3_StrokeStart),
@(thirdCirlce_Stage4_StrokeStart),
@(thirdCirlce_Stage5_StrokeStart)];
return thirdCirlce_StrokeEnd_Values;
}
@end
//
// ZZCenterRotateView.h
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "ZZCircleView.h"
typedef void(^firstBallDidRestoreCallBack)(void);
@interface ZZCenterRotateView :
UIView
/**
* 第一个点
*/
@property(nonatomic,strong)
ZZCircleView *firstDot;
/**
* 第二个点
*/
@property(nonatomic,strong)
ZZCircleView *secondDot;
/**
* 第三个点
*/
@property(nonatomic,strong)
ZZCircleView *thirdDot;
/**
* 执行完后回调的block
*/
@property(nonatomic,copy)
firstBallDidRestoreCallBack dotAniationFinishHandler;
/**
* 旋转动画
*/
- (void)rotateAnimation;
/**
* 移除动画
*/
- (void)removeAnimations;
@end
//
// ZZCenterRotateView.m
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZCenterRotateView.h"
#import "ZZLoaderView.h"
@implementation ZZCenterRotateView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super
initWithFrame:frame]) {
[self
setUpDotViews];
}
return
self;
}
- (void)setUpDotViews {
self.firstDot = [ZZCircleView
layer];
self.secondDot = [ZZCircleView
layer];
self.thirdDot = [ZZCircleView
layer];
[self.layer
addSublayer:_firstDot];
[self.layer
addSublayer:_secondDot];
[self.layer
addSublayer:_thirdDot];
CGFloat dotWidth =
self.frame.size.width *
3 / 4 /
2;
CGRect firstDotFrame =
CGRectMake(0,
0, dotWidth, dotWidth);
CGRect secondDotFrame =
CGRectMake(0,
self.frame.size.height-dotWidth,
dotWidth, dotWidth);
CGRect thirdDotFrame =
CGRectMake(self.frame.size.width-dotWidth,
secondDotFrame.origin.y, dotWidth, dotWidth);
self.firstDot.frame = firstDotFrame;
self.secondDot.frame = secondDotFrame;
self.thirdDot.frame = thirdDotFrame;
}
- (void)rotateAnimation {
CABasicAnimation *rotateAnimation = [CABasicAnimation
animationWithKeyPath:@"transform.rotation.z"];
rotateAnimation.fromValue =
@(0.0);
rotateAnimation.toValue =
@(M_PI/2);
rotateAnimation.duration =
ZZRotateAnimationTime;
rotateAnimation.fillMode =
kCAFillModeForwards;
rotateAnimation.removedOnCompletion =
false;
rotateAnimation.delegate =
self;
[rotateAnimation setValue:@"rotateAnimation"
forKey:@"animationName"];
[self.layer
addAnimation:rotateAnimation
forKey:nil];
}
- (void)removeAnimations {
[self.layer
removeAllAnimations];
[[self
firstDot]
removeAllAnimations];
}
- (void)firstDotMoveAnimation {
CGFloat endX =
self.frame.size.width
- self.firstDot.frame.size.width+self.firstDot.frame.size.width/2;
CABasicAnimation *moveAnimation = [CABasicAnimation
animationWithKeyPath:@"position.x"];
moveAnimation.toValue = [[NSNumber
alloc] initWithFloat:endX];
moveAnimation.fromValue =
@(self.firstDot.frame.size.width/2);
moveAnimation.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseIn];
// moveAnimation.fillMode = kCAFillModeForwards;
moveAnimation.duration =
ZZFirstDotMoveAnimationTime;
// moveAnimation.repeatCount = 1000;
// moveAnimation.removedOnCompletion = false;
// [self.firstDot addAnimation:moveAnimation forKey:@"moveAnimation"];
CABasicAnimation *changeAnimation = [CABasicAnimation
animationWithKeyPath:@"factor"];
changeAnimation.toValue =
@(1);
changeAnimation.fromValue =
@(0);
changeAnimation.fillMode =
kCAFillModeForwards;
changeAnimation.duration =
ZZFirstDotMoveAnimationTime;
// changeAnimation.delegate = self ;
// changeAnimation.repeatCount = 1;
// changeAnimation.removedOnCompletion = false;
// [self.firstDot addAnimation:changeAnimation forKey:@"changeAnimation"];
CAAnimationGroup *group = [CAAnimationGroup
animation];
group.animations =
@[moveAnimation,changeAnimation];
group.duration =
ZZFirstDotMoveAnimationTime;
group.removedOnCompletion =
false;
group.fillMode =
kCAFillModeForwards;
group.delegate =
self;
group.beginTime = [self.firstDot
convertTime:CACurrentMediaTime()
toLayer:nil] +
0.1;
[group setValue:@"firstDotGroup"
forKey:@"animationName"];
[self.firstDot
addAnimation:group
forKey:@"firstDotGroup"];
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
NSString *animationName = [anim
valueForKey:@"animationName"];
if ([animationName
isEqualToString:@"rotateAnimation"] ) {
[self
firstDotMoveAnimation];
}
else
if ([animationName isEqualToString:@"firstDotGroup"] ) {
self.firstDot.factor =
1;
self.firstDot.frame =
CGRectMake(self.frame.size.width
- self.firstDot.frame.size.width,
self.firstDot.frame.origin.y,
self.firstDot.frame.size.width,
self.firstDot.frame.size.height);
[self
firstDotRestoreAnimation];
} else
if ([animationName
isEqualToString:@"restoreAnimation"] ) {
[self.layer
removeAllAnimations];
[self.firstDot
removeAllAnimations];
self.firstDot.factor =
0;
[self
restoreFirstDotPosition];
__weak
typeof(self) weakSelf =
self ;
dispatch_time_t delay =
dispatch_time(DISPATCH_TIME_NOW,
NSEC_PER_MSEC *200);
dispatch_after(delay,
dispatch_get_main_queue(), ^{
if(weakSelf !=
nil) {
weakSelf.dotAniationFinishHandler();
}
});
}
}
-(void)firstDotRestoreAnimation {
[self.firstDot
removeAnimationForKey:@"firstDotGroup"];
NSMutableArray *values = [self
springAnimationValues:@(1)
toValue:@(0)
usingSpringWithDamping:4
initialSpringVelocity:10
duration:ZZFirstDotRestoreAnimationTime];
CAKeyframeAnimation *restoreAnimation = [CAKeyframeAnimation
animationWithKeyPath:@"factor"];
restoreAnimation.values = values;
restoreAnimation.duration =
ZZFirstDotRestoreAnimationTime;
restoreAnimation.fillMode =
kCAFillModeForwards;
restoreAnimation.removedOnCompletion =
false;
restoreAnimation.delegate =
self ;
[restoreAnimation setValue:@"restoreAnimation"
forKey:@"animationName"];
[self.firstDot
addAnimation:restoreAnimation
forKey:@"restoreAnimation"];
}
- (void)restoreFirstDotPosition {
[CATransaction
begin];
[CATransaction
setDisableActions:YES];
self.firstDot.frame =
CGRectMake(0,
self.firstDot.frame.origin.y,
self.firstDot.frame.size.width,
self.firstDot.frame.size.height);
[CATransaction
commit];
}
- (NSMutableArray *)springAnimationValues:(id)fromValue
toValue:(id)toValue
usingSpringWithDamping:(CGFloat)damping
initialSpringVelocity:(CGFloat)velocity
duration:(CGFloat)duration {
// 60个关键帧
NSInteger numOfFrames = duration *
60;
NSMutableArray *values = [NSMutableArray
arrayWithCapacity:numOfFrames];
for (NSInteger i =
0; i < numOfFrames; i++) {
[values addObject:@(0.0)];
}
//差值
CGFloat diff = [toValue
floatValue] - [fromValue
floatValue];
for (NSInteger frame =
0; frame < numOfFrames; frame++) {
CGFloat x = (CGFloat)frame / (CGFloat)numOfFrames;
CGFloat value = [toValue
floatValue] -
diff * (pow(M_E, -damping * x) *
cos(velocity * x));
// y = 1-e^{-5x} * cos(30x)
values[frame] = @(value);
}
return values;
}
@end
//
// ZZProgressHUD.h
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, ZZProgressHUDBackgroundType) {
ZZProgressHUDBackgroundTypeNone,
ZZProgressHUDBackgroundTypeDim,
ZZProgressHUDBackgroundTypeBlur,
};
@interface ZZProgressHUD :
UIView
@property (nonatomic,
assign)
ZZProgressHUDBackgroundType backgroundType;
+ (ZZProgressHUD *)hudForView:(UIView *)view;
+ (ZZProgressHUD *)sharedHUD;
- (void)show:(BOOL)animated;
- (void)hide:(BOOL)animated;
+ (void)showSharedHUD:(BOOL)animated withType:(ZZProgressHUDBackgroundType)type;
+ (void)hideSharedHUD:(BOOL)animated;
@end
//
// ZZProgressHUD.m
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZProgressHUD.h"
#import "ZZLoaderView.h"
@interface
ZZProgressHUD()
@property (nonatomic,
strong) UIVisualEffectView *blurView;
@property (nonatomic,
strong) ZZLoaderView *indecatorView;
@end
@implementation ZZProgressHUD
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super
initWithFrame:frame]) {
self.alpha =
0;
[self
setupViewsWith:ZZProgressHUDBackgroundTypeNone];
}
return
self;
}
+ (ZZProgressHUD *)hudForView:(UIView *)view {
ZZProgressHUD *hud = [[ZZProgressHUD
alloc]
initWithFrame:view.frame];
[view addSubview:hud];
return hud;
}
+ (ZZProgressHUD *)sharedHUD{
static
ZZProgressHUD * sharedInstance;
static
dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[ZZProgressHUD
alloc] initWithFrame:CGRectMake(0,
0,[UIScreen
mainScreen].bounds.size.width,
[UIScreen mainScreen].bounds.size.height)];
});
return sharedInstance;
}
- (void)setBackgroundType:(ZZProgressHUDBackgroundType)backgroundType {
_backgroundType = backgroundType;
switch (backgroundType) {
case
ZZProgressHUDBackgroundTypeNone:
self.backgroundColor = [UIColor
clearColor];
_blurView.hidden =
true;
break;
case
ZZProgressHUDBackgroundTypeDim:
self.backgroundColor =
ZZRGBA(0,
0, 0,
0.6);
_blurView.hidden =
true;
break;
case
ZZProgressHUDBackgroundTypeBlur:
self.blurView.hidden =
false;
self.backgroundColor = [UIColor
clearColor];
break;
default:
break;
}
}
- (void)setupViewsWith:(ZZProgressHUDBackgroundType)type {
self.indecatorView = [[ZZLoaderView
alloc] initWithFrame:CGRectMake(0,
0, ZZCircleRadius*2+30,
ZZCircleRadius*2+30)];
_indecatorView.center =
self.center;
_indecatorView.layer.cornerRadius =
5;
_indecatorView.layer.masksToBounds =
true;
_indecatorView.backgroundColor =
ZZRGBA(81,
88, 128,
0.8);
self.blurView = [[UIVisualEffectView
alloc]
initWithFrame:self.frame];
_blurView.effect = [UIBlurEffect
effectWithStyle:UIBlurEffectStyleLight];
[self
addSubview:self.blurView];
switch (type) {
case
ZZProgressHUDBackgroundTypeNone:
_blurView.hidden =
true;
break;
case
ZZProgressHUDBackgroundTypeDim:
self.backgroundColor =
ZZRGBA(0,
0, 0,
0.6);
_blurView.hidden =
true;
break;
case
ZZProgressHUDBackgroundTypeBlur:
break;
default:
break;
}
[self
addSubview:_indecatorView];
}
- (void)show:(BOOL)animated {
NSAssert(self.superview,
@"ZZFundHud should have a superview");
if(animated) {
[UIView
animateWithDuration:0.2
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.alpha =
1;
} completion:^(BOOL completed){
}];
} else {
self.alpha =
1;
}
}
- (void)hide:(BOOL)animated {
if (animated) {
[UIView
animateWithDuration:0.2
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.alpha =
0;
} completion:^(BOOL completed){
[self
removeFromSuperview];
[self.indecatorView
stopLoading];
}];
} else {
self.alpha =
0;
[self
removeFromSuperview];
[self.indecatorView
stopLoading];
}
}
+ (void)showSharedHUD:(BOOL)animated withType:(ZZProgressHUDBackgroundType)type
{
UIView *window = [UIApplication
sharedApplication].windows.lastObject;
ZZProgressHUD *sharedHUD = [ZZProgressHUD
sharedHUD];
sharedHUD.backgroundType = type;
[window addSubview:sharedHUD];
[sharedHUD show:animated];
}
+ (void)hideSharedHUD:(BOOL)animated {
[[ZZProgressHUD
sharedHUD] hide:animated];
}
@end
//
// ViewController.h
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ViewController :
UIViewController
@end
//
// ViewController.m
// 14-自定义特效的HUD
//
// Created by 周昭 on 16/12/13.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ViewController.h"
#import "ZZProgressHUD.h"
@interface
ViewController ()
- (IBAction)showDimHUD:(UIButton *)button;
- (IBAction)showDefaultHUD:(UIButton *)button;
- (IBAction)showBlurHUD:(UIButton *)button;
- (IBAction)showSharedHUD:(UIButton *)button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super
viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super
didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)showDimHUD:(UIButton *)button {
ZZProgressHUD *hud = [ZZProgressHUD
hudForView:self.view];
hud.backgroundType =
ZZProgressHUDBackgroundTypeDim;
[hud show:YES];
[self
performHideAfterSecond:5
hud:hud];
}
- (IBAction)showDefaultHUD:(UIButton *)button {
ZZProgressHUD *hud = [ZZProgressHUD
hudForView:self.view];
hud.backgroundType =
ZZProgressHUDBackgroundTypeNone;
[hud show:YES];
[self
performHideAfterSecond:5
hud:hud];
}
- (IBAction)showBlurHUD:(UIButton *)button {
ZZProgressHUD *hud = [ZZProgressHUD
hudForView:self.view];
hud.backgroundType =
ZZProgressHUDBackgroundTypeBlur;
[hud show:YES];
[self
performHideAfterSecond:5
hud:hud];
}
- (IBAction)showSharedHUD:(UIButton *)button {
[ZZProgressHUD
showSharedHUD:YES
withType:ZZProgressHUDBackgroundTypeBlur];
[self
performHideAfterSecond:5
hud:[ZZProgressHUD
sharedHUD]];
}
- (void)performHideAfterSecond:(double)sec hud:(ZZProgressHUD *)hud {
uint64_t msc = sec *
1000;
dispatch_time_t delay =
dispatch_time(DISPATCH_TIME_NOW,
NSEC_PER_MSEC * msc);
dispatch_after(delay,
dispatch_get_main_queue(), ^{
[hud hide:true];
});
}
@end
相关文章推荐
- asp.net 自己封装数据库操作一个类中一个自定义方法Execute(),非常实用,省去了麻烦的中间过程,动态参数
- 一个基于MBProgressHUD的自定义视图hud例子
- 极限编程(ExtremeProgramming,简称XP)是一个轻量级的、灵巧的软件开发方法,同时它也是一个非常严谨和周密的方法
- 构建一个轻量级的嵌入式虚拟平台,开发工程用板stm32 picoc解释器,大量自定义函数,sarm拓展,lwip移植,nes模拟器移植,系统优化,等等技术的融合
- 从0开始写一个基于注解的轻量级分布式RPC框架(4)自定义Spring的IOC,自定义属性注入bean的过程
- 从0开始写一个基于注解的轻量级分布式RPC框架(3)让Spring加载自定义注解
- 一个自定义的简单的类似于HUD的加载提示框
- python自定义一个非常简易的模块
- 自定义View_一个非常简洁的柱状图
- 一个非常有用的自定义聚集函数
- Qt自定义带游标的slider,在滑块正上方显示当前值(非常有意思,继承QSlider之后增加一个QLabel,然后不断移动它)
- 大家用了这么久的.net有没有发现C#中可以用中文变量呀!!可用这个特性来彻底改变程序的易读性(搞笑).但其实有一个非常独特的用处的
- 一个非常不错的业务规则管理器
- 如何使用Css样式自定义一个DataGrid的风格
- [ASP]一个非常简洁的验证码程序
- 一个可以弹出确认对话框的自定义Web服务器控件ConfirmButton
- 对"一个非常难的查询问题(部门上下级的关系)"之解答的完善
- 一个非常简单,非常短小的线程池
- Tomcat4.1.12在处理自定义tag时的一个缺陷
- 介绍一个轻量级的C++开发工具——Relo