程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 開源提示框SVProgressHUD使用備忘錄

開源提示框SVProgressHUD使用備忘錄

編輯:C++入門知識

[cpp]
//  
//  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.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

 


[cpp]
//  
//  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 *possibleKeyboard in [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 

//
//  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 *possibleKeyboard in [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


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved