SVProgressHUD

来源:互联网 发布:国内投资公司知乎 编辑:程序博客网 时间:2024/04/30 00:46

//

//  SVProgressHUD.h

//

//  Created by Sam Vermette on 27.03.11.

//  Copyright 2011 Sam Vermette. All rights reserved.

//

//  https://github.com/samvermette/SVProgressHUD

//


#import <UIKit/UIKit.h>

#import <AvailabilityMacros.h>


enum {

//    允许用户进行其他界面操作

    SVProgressHUDMaskTypeNone = 1,// allow user interactions while HUD is displayed

//    不允许用户进行其他界面操作

    SVProgressHUDMaskTypeClear, // don't allow

    

    SVProgressHUDMaskTypeBlack, // don't allow and dim the UI in the back of the HUD

    SVProgressHUDMaskTypeGradient // don't allow and dim the UI with a a-la-alert-view bg gradient

};


typedef NSUInteger SVProgressHUDMaskType;


@interface SVProgressHUD : UIView

//展示提示框

+ (void)show;

+ (void)showWithStatus:(NSString*)status;

+ (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;

+ (void)showWithMaskType:(SVProgressHUDMaskType)maskType;


+ (void)showSuccessWithStatus:(NSString*)string;

+ (void)showSuccessWithStatus:(NSString *)string duration:(NSTimeInterval)duration;

+ (void)showErrorWithStatus:(NSString *)string;

+ (void)showErrorWithStatus:(NSString *)string duration:(NSTimeInterval)duration;

//改变当前正在展示的提示框文字

+ (void)setStatus:(NSString*)string;// change the HUD loading status while it's showing

//关闭当前提示

+ (void)dismiss;// simply dismiss the HUD with a fade+scale out animation

+ (void)dismissWithSuccess:(NSString*)successString;// also displays the success icon image

+ (void)dismissWithSuccess:(NSString*)successString afterDelay:(NSTimeInterval)seconds;

+ (void)dismissWithError:(NSString*)errorString;// also displays the error icon image

+ (void)dismissWithError:(NSString*)errorString afterDelay:(NSTimeInterval)seconds;


+ (BOOL)isVisible;


@end




//

//  SVProgressHUD.m

//

//  Created by Sam Vermette on 27.03.11.

//  Copyright 2011 Sam Vermette. All rights reserved.

//

//  https://github.com/samvermette/SVProgressHUD

//


#import "SVProgressHUD.h"

#import <QuartzCore/QuartzCore.h>


@interface SVProgressHUD ()


@property (nonatomic,readwrite) SVProgressHUDMaskType maskType;

@property (nonatomic,strong,readonly) NSTimer *fadeOutTimer;


@property (nonatomic,strong,readonly) UIWindow *overlayWindow;

@property (nonatomic,strong,readonly) UIView *hudView;

@property (nonatomic,strong,readonly) UILabel *stringLabel;

@property (nonatomic,strong,readonly) UIImageView *imageView;

@property (nonatomic,strong,readonly) UIActivityIndicatorView *spinnerView;


@property (nonatomic,readonly) CGFloat visibleKeyboardHeight;


- (void)showWithStatus:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType networkIndicator:(BOOL)show;

- (void)setStatus:(NSString*)string;

- (void)registerNotifications;

- (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle;

- (void)positionHUD:(NSNotification*)notification;


- (void)dismiss;

- (void)dismissWithStatus:(NSString*)string error:(BOOL)error;

- (void)dismissWithStatus:(NSString*)string error:(BOOL)error afterDelay:(NSTimeInterval)seconds;


@end



@implementation SVProgressHUD


@synthesize overlayWindow, hudView, maskType, fadeOutTimer, stringLabel, imageView, spinnerView, visibleKeyboardHeight;


- (void)dealloc {

self.fadeOutTimer =nil;

    [[NSNotificationCenter defaultCenter] removeObserver:self];

}



+ (SVProgressHUD*)sharedView {

    static dispatch_once_t once;

    static SVProgressHUD *sharedView;

    dispatch_once(&once, ^ { sharedView = [[SVProgressHUD alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; });

    return sharedView;

}



+ (void)setStatus:(NSString *)string {

[[SVProgressHUD sharedView] setStatus:string];

}


#pragma mark - Show Methods


+ (void)show {

    [[SVProgressHUD sharedView] showWithStatus:nil maskType:SVProgressHUDMaskTypeNone networkIndicator:NO];

}


+ (void)showWithStatus:(NSString *)status {

    [[SVProgressHUD sharedView] showWithStatus:status maskType:SVProgressHUDMaskTypeNone networkIndicator:NO];

}


+ (void)showWithMaskType:(SVProgressHUDMaskType)maskType {

    [[SVProgressHUD sharedView] showWithStatus:nil maskType:maskType networkIndicator:NO];

}


+ (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType {

    [[SVProgressHUD sharedView] showWithStatus:status maskType:maskType networkIndicator:NO];

}


+ (void)showSuccessWithStatus:(NSString *)string {

    [SVProgressHUD showSuccessWithStatus:string duration:1];

}


+ (void)showSuccessWithStatus:(NSString *)string duration:(NSTimeInterval)duration {

    [SVProgressHUD show];

    [SVProgressHUD dismissWithSuccess:string afterDelay:duration];

}


+ (void)showErrorWithStatus:(NSString *)string {

    [SVProgressHUD showErrorWithStatus:string duration:1];

}


+ (void)showErrorWithStatus:(NSString *)string duration:(NSTimeInterval)duration {

    [SVProgressHUD show];

    [SVProgressHUD dismissWithError:string afterDelay:duration];

}



#pragma mark - Dismiss Methods


+ (void)dismiss {

[[SVProgressHUD sharedView] dismiss];

}


+ (void)dismissWithSuccess:(NSString*)successString {

[[SVProgressHUD sharedView] dismissWithStatus:successString error:NO];

}


+ (void)dismissWithSuccess:(NSString *)successString afterDelay:(NSTimeInterval)seconds {

    [[SVProgressHUD sharedView] dismissWithStatus:successString error:NO afterDelay:seconds];

}


+ (void)dismissWithError:(NSString*)errorString {

[[SVProgressHUD sharedView] dismissWithStatus:errorString error:YES];

}


+ (void)dismissWithError:(NSString *)errorString afterDelay:(NSTimeInterval)seconds {

    [[SVProgressHUD sharedView] dismissWithStatus:errorString error:YES afterDelay:seconds];

}



#pragma mark - Instance Methods


- (id)initWithFrame:(CGRect)frame {

    if ((self = [super initWithFrame:frame])) {

self.userInteractionEnabled =NO;

        self.backgroundColor = [UIColor clearColor];

self.alpha =0;

        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    }

    return self;

}


- (void)drawRect:(CGRect)rect {

    

    CGContextRef context = UIGraphicsGetCurrentContext();

    

    switch (self.maskType) {

            

        case SVProgressHUDMaskTypeBlack: {

            [[UIColor colorWithWhite:0 alpha:0.5] set];

            CGContextFillRect(context, self.bounds);

            break;

        }

            

        case SVProgressHUDMaskTypeGradient: {

            

            size_t locationsCount = 2;

            CGFloat locations[2] = {0.0f,1.0f};

            CGFloat colors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f}; 

            CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

            CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount);

            CGColorSpaceRelease(colorSpace);

            

            CGPoint center = CGPointMake(self.bounds.size.width/2,self.bounds.size.height/2);

            float radius = MIN(self.bounds.size.width ,self.bounds.size.height) ;

            CGContextDrawRadialGradient (context, gradient, center, 0, center, radius, kCGGradientDrawsAfterEndLocation);

            CGGradientRelease(gradient);

            

            break;

        }

    }

}


- (void)setStatus:(NSString *)string {

    CGFloat hudWidth = 100;

    CGFloat hudHeight = 100;

    CGFloat stringWidth = 0;

    CGFloat stringHeight = 0;

    CGRect labelRect = CGRectZero;

    

    if(string) {

        CGSize stringSize = [string sizeWithFont:self.stringLabel.font constrainedToSize:CGSizeMake(200,300)];

        stringWidth = stringSize.width;

        stringHeight = stringSize.height;

        hudHeight = 80+stringHeight;

        

        if(stringWidth > hudWidth)

            hudWidth = ceil(stringWidth/2)*2;

        

        if(hudHeight > 100) {

            labelRect = CGRectMake(12, 66, hudWidth, stringHeight);

            hudWidth+=24;

        } else {

            hudWidth+=24;  

            labelRect = CGRectMake(0, 66, hudWidth, stringHeight);   

        }

    }

self.hudView.bounds = CGRectMake(0,0, hudWidth, hudHeight);

    if(string)

        self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2,36);

else

       self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, CGRectGetHeight(self.hudView.bounds)/2);

self.stringLabel.hidden =NO;

self.stringLabel.text = string;

self.stringLabel.frame = labelRect;

if(string)

self.spinnerView.center = CGPointMake(ceil(CGRectGetWidth(self.hudView.bounds)/2)+0.5,40.5);

else

self.spinnerView.center = CGPointMake(ceil(CGRectGetWidth(self.hudView.bounds)/2)+0.5, ceil(self.hudView.bounds.size.height/2)+0.5);

}


- (void)setFadeOutTimer:(NSTimer *)newTimer {

    

    if(fadeOutTimer)

        [fadeOutTimer invalidate], fadeOutTimer = nil;

    

    if(newTimer)

        fadeOutTimer = newTimer;

}



- (void)registerNotifications {

    [[NSNotificationCenter defaultCenter] addObserver:self 

                                             selector:@selector(positionHUD:) 

                                                 name:UIApplicationDidChangeStatusBarOrientationNotification 

                                               object:nil];  

    

    [[NSNotificationCenter defaultCenter] addObserver:self 

                                             selector:@selector(positionHUD:) 

                                                 name:UIKeyboardWillHideNotification

                                               object:nil];

    

    [[NSNotificationCenter defaultCenter] addObserver:self 

                                             selector:@selector(positionHUD:) 

                                                 name:UIKeyboardDidHideNotification

                                               object:nil];

    

    [[NSNotificationCenter defaultCenter] addObserver:self 

                                             selector:@selector(positionHUD:) 

                                                 name:UIKeyboardWillShowNotification

                                               object:nil];

    

    [[NSNotificationCenter defaultCenter] addObserver:self 

                                             selector:@selector(positionHUD:) 

                                                 name:UIKeyboardDidShowNotification

                                               object:nil];

}



- (void)positionHUD:(NSNotification*)notification {

    

    CGFloat keyboardHeight;

    double animationDuration;

    

    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];

    

    if(notification) {

        NSDictionary* keyboardInfo = [notification userInfo];

        CGRect keyboardFrame = [[keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];

        animationDuration = [[keyboardInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

        

        if(notification.name == UIKeyboardWillShowNotification || notification.name == UIKeyboardDidShowNotification) {

            if(UIInterfaceOrientationIsPortrait(orientation))

                keyboardHeight = keyboardFrame.size.height;

            else

                keyboardHeight = keyboardFrame.size.width;

        } else

            keyboardHeight = 0;

    } else {

        keyboardHeight = self.visibleKeyboardHeight;

    }

    

    CGRect orientationFrame = [UIScreen mainScreen].bounds;

    CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;

    

    if(UIInterfaceOrientationIsLandscape(orientation)) {

        float temp = orientationFrame.size.width;

        orientationFrame.size.width = orientationFrame.size.height;

        orientationFrame.size.height = temp;

        

        temp = statusBarFrame.size.width;

        statusBarFrame.size.width = statusBarFrame.size.height;

        statusBarFrame.size.height = temp;

    }

    

    CGFloat activeHeight = orientationFrame.size.height;

    

    if(keyboardHeight > 0)

        activeHeight += statusBarFrame.size.height*2;

    

    activeHeight -= keyboardHeight;

    CGFloat posY = floor(activeHeight*0.45);

    CGFloat posX = orientationFrame.size.width/2;

    

    CGPoint newCenter;

    CGFloat rotateAngle;

    

    switch (orientation) { 

        case UIInterfaceOrientationPortraitUpsideDown:

            rotateAngle = M_PI; 

            newCenter = CGPointMake(posX, orientationFrame.size.height-posY);

            break;

        case UIInterfaceOrientationLandscapeLeft:

            rotateAngle = -M_PI/2.0f;

            newCenter = CGPointMake(posY, posX);

            break;

        case UIInterfaceOrientationLandscapeRight:

            rotateAngle = M_PI/2.0f;

            newCenter = CGPointMake(orientationFrame.size.height-posY, posX);

            break;

        default:// as UIInterfaceOrientationPortrait

            rotateAngle = 0.0;

            newCenter = CGPointMake(posX, posY);

            break;

    } 

    

    if(notification) {

        [UIView animateWithDuration:animationDuration 

                              delay:0 

                            options:UIViewAnimationOptionAllowUserInteraction 

                         animations:^{

                             [self moveToPoint:newCenter rotateAngle:rotateAngle];

                         } completion:NULL];

    } 

    

    else {

        [self moveToPoint:newCenter rotateAngle:rotateAngle];

    }

    

}


- (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle {

    self.hudView.transform = CGAffineTransformMakeRotation(angle); 

    self.hudView.center = newCenter;

}


#pragma mark - Master show/dismiss methods


- (void)showWithStatus:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType networkIndicator:(BOOL)show {

    dispatch_async(dispatch_get_main_queue(), ^{

        if(!self.superview)

            [self.overlayWindow addSubview:self];

        

        self.fadeOutTimer = nil;

        self.imageView.hidden = YES;

        self.maskType = hudMaskType;

        

        [self setStatus:string];

        [self.spinnerView startAnimating];

        

        if(self.maskType != SVProgressHUDMaskTypeNone) {

            self.overlayWindow.userInteractionEnabled =YES;

        } else {

            self.overlayWindow.userInteractionEnabled =NO;

        }

        

        [self.overlayWindow makeKeyAndVisible];

        [self positionHUD:nil];

        

        if(self.alpha !=1) {

            [self registerNotifications];

            self.hudView.transform = CGAffineTransformScale(self.hudView.transform,1.3,1.3);

            

            [UIView animateWithDuration:0.15

                                  delay:0

                                options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState

                             animations:^{

                                 self.hudView.transform = CGAffineTransformScale(self.hudView.transform,1/1.3,1/1.3);

                                 self.alpha = 1;

                             }

                             completion:NULL];

        }

        

        [self setNeedsDisplay];

    });

}



- (void)dismissWithStatus:(NSString*)string error:(BOOL)error {

[self dismissWithStatus:string error:error afterDelay:0.9];

}



- (void)dismissWithStatus:(NSString *)string error:(BOOL)error afterDelay:(NSTimeInterval)seconds {

    dispatch_async(dispatch_get_main_queue(), ^{

        if(self.alpha !=1)

            return;

        

        if(error)

            self.imageView.image = [UIImage imageNamed:@"SVProgressHUD.bundle/error.png"];

        else

            self.imageView.image = [UIImage imageNamed:@"SVProgressHUD.bundle/success.png"];

        

        self.imageView.hidden = NO;

        [self setStatus:string];

        [self.spinnerView stopAnimating];

        

        self.fadeOutTimer = [NSTimer scheduledTimerWithTimeInterval:seconds target:self selector:@selector(dismiss) userInfo:nil repeats:NO];

    });

}


- (void)dismiss {

    dispatch_async(dispatch_get_main_queue(), ^{


        [UIView animateWithDuration:0.15

                              delay:0

                            options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction

                         animations:^{

                             self.hudView.transform = CGAffineTransformScale(self.hudView.transform,0.8,0.8);

                             self.alpha = 0;

                         }

                         completion:^(BOOL finished){ 

                             if(self.alpha ==0) {

                                 [[NSNotificationCenter defaultCenter] removeObserver:self];

                                 [hudView removeFromSuperview];

                                 hudView = nil;

                                 

                                 // Make sure to remove the overlay window from the list of windows

                                 // before trying to find the key window in that same list

                                 NSMutableArray *windows = [[NSMutableArray alloc] initWithArray:[UIApplication sharedApplication].windows];

                                 [windows removeObject:overlayWindow];

                                 overlayWindow = nil;

                                 

                                 [windows enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(UIWindow *window, NSUInteger idx,BOOL *stop) {

                                   if([window isKindOfClass:[UIWindow class]] && window.windowLevel == UIWindowLevelNormal) {

                                     [window makeKeyWindow];

                                     *stop = YES;

                                   }

                                 }];

                                 

                                 // uncomment to make sure UIWindow is gone from app.windows

                                 //NSLog(@"%@", [UIApplication sharedApplication].windows);

                                 //NSLog(@"keyWindow = %@", [UIApplication sharedApplication].keyWindow);

                             }

                         }];

    });

}


#pragma mark - Utilities


+ (BOOL)isVisible {

    return ([SVProgressHUD sharedView].alpha ==1);

}



#pragma mark - Getters


- (UIWindow *)overlayWindow {

    if(!overlayWindow) {

        overlayWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

        overlayWindow.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

        overlayWindow.backgroundColor = [UIColor clearColor];

        overlayWindow.userInteractionEnabled = NO;

    }

    return overlayWindow;

}


- (UIView *)hudView {

    if(!hudView) {

        hudView = [[UIView alloc] initWithFrame:CGRectZero];

        hudView.layer.cornerRadius = 10;

hudView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8];

        hudView.autoresizingMask = (UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin |

                                    UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin);

        

        [self addSubview:hudView];

    }

    return hudView;

}


- (UILabel *)stringLabel {

    if (stringLabel == nil) {

        stringLabel = [[UILabel alloc] initWithFrame:CGRectZero];

stringLabel.textColor = [UIColor whiteColor];

stringLabel.backgroundColor = [UIColor clearColor];

stringLabel.adjustsFontSizeToFitWidth = YES;

stringLabel.textAlignment = UITextAlignmentCenter;

stringLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;

stringLabel.font = [UIFont boldSystemFontOfSize:16];

stringLabel.shadowColor = [UIColor blackColor];

stringLabel.shadowOffset = CGSizeMake(0, -1);

        stringLabel.numberOfLines = 0;

    }

    

    if(!stringLabel.superview)

        [self.hudView addSubview:stringLabel];

    

    return stringLabel;

}


- (UIImageView *)imageView {

    if (imageView == nil)

        imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,28, 28)];

    

    if(!imageView.superview)

        [self.hudView addSubview:imageView];

    

    return imageView;

}


- (UIActivityIndicatorView *)spinnerView {

    if (spinnerView == nil) {

        spinnerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

spinnerView.hidesWhenStopped = YES;

spinnerView.bounds = CGRectMake(0,0,37, 37);

    }

    

    if(!spinnerView.superview)

        [self.hudView addSubview:spinnerView];

    

    return spinnerView;

}


- (CGFloat)visibleKeyboardHeight {

        

    UIWindow *keyboardWindow = nil;

    for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {

        if(![[testWindow class] isEqual:[UIWindow class]]) {

            keyboardWindow = testWindow;

            break;

        }

    }


    // Locate UIKeyboard.  

    UIView *foundKeyboard = nil;

    for (__strong UIView *possibleKeyboardin [keyboardWindow subviews]) {

        

        // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView.

        if ([[possibleKeyboard description] hasPrefix:@"<UIPeripheralHostView"]) {

            possibleKeyboard = [[possibleKeyboard subviews] objectAtIndex:0];

        }                                                                                

        

        if ([[possibleKeyboard description] hasPrefix:@"<UIKeyboard"]) {

            foundKeyboard = possibleKeyboard;

            break;

        }

    }

        

    if(foundKeyboard && foundKeyboard.bounds.size.height >100)

        return foundKeyboard.bounds.size.height;

    

    return 0;

}


@end




0 0
原创粉丝点击