iOS开发-自定义HUD(非常轻量级)

今天呢给同学带来的是一个非常轻量级的自定义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.durationZZRotateAnimationTime;

    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 sharedHUDhide: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

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
XNProgressHUD (https://github.com/LuohanCC/XNProgressHUD) 一款支持支持自定义轻量级HUD,支持垂直、水平两种样式。SVProgressHUD非常灵活,所见的部分都可根据自己的要求进行自定义,包括自义动画效果或图片,只需要实现相关协议方法。 安装使用 pod 'XNProgressHUD' 使用说明 在Window上显示: [XNHUD showLoadingWithTitle:@"正在登录"]; [XNHUD showWithTitle:@"这是一个支持自定义轻量级HUD"]; [XNHUD showInfoWithTitle:@"邮箱地址不能为空"]; [XNHUD showErrorWithTitle:@"拒绝访问"]; [XNHUD showSuccessWithTitle:@"操作成功"]; 在ViewController上显示(maskType.enable=true时,导航栏依然可以接受点击事件) // 引入'UIViewController XNProgressHUD.h' [self.hud showLoadingWithTitle:@"正在登录"]; [self.hud showWithTitle:@"这是一个支持自定义轻量级HUD"]; [self.hud showInfoWithTitle:@"邮箱地址不能为空"]; [self.hud showErrorWithTitle:@"拒绝访问"]; [self.hud showSuccessWithTitle:@"操作成功"]; // 设置显示位置 [XNHUD setPosition:CGPointMake(self.view.bounds.size.width/2, self.view.bounds.size.height * 0.7)]; // 设置主色调 [XNHUD setTintColor:[UIColor colorWithRed:38/255.0 green:50/255.0 blue:56/255.0 alpha:0.8]]; // 设置相应的maskType转态下的颜色(16进制颜色值) [XNHUD setMaskType:(XNProgressHUDMaskTypeBlack) hexColor:0x00000044]; [XNHUD setMaskType:(XNProgressHUDMaskTypeCustom) hexColor:0xff000044]; 属性和方法说明 显示时长minimumDelayDismissDuration作用于非加载样式的视图:XNRefreshViewStyleInfoImage、XNRefreshViewStyleError、XNRefreshViewStyleSuccess; 显示时长maximumDelayDismissDuration作用与加载样式的视图:XNRefreshViewStyleLoading、XNRefreshViewStyleProgress。 @property (nonatomic, assign) NSTimeInterval minimumDelayDismissDuration; //default:1.5f @property (nonatomic, assign) NSTimeInterval maximumDelayDismissDuration; //default:20.f 延时显示时间和延时消失时间,该方法只对下一次HUD显示生效(只生效一次)。 [XNHUD setDisposableDelayResponse:1.0f delayDismiss:2.0f]; 设置排列方向,默认为水平方向 [XNHUD setOrientation:XNProgressHUDOrientationHorizontal]; 自定义XNProgressHUD 如果需要自定义加载视图的显示内容和动画样式,请重写XNRefreshView并实现XNRefreshViewProtocol中的协议方法即可,具体如下 1.自定义XNRefreshView并实现XNRefreshViewProtocol中的协议方法; 2.继承XNProgressHUD并实现XNProgressHUDMethod中的协议方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值