daily pastebin goal
38%
SHARE
TWEET

ARC support for SVProgressHUD.m

pabloroca Oct 19th, 2011 289 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. //  SVProgressHUD.m
  3. //
  4. //  Created by Sam Vermette on 27.03.11.
  5. //  Copyright 2011 Sam Vermette. All rights reserved.
  6. //
  7. //  https://github.com/samvermette/SVProgressHUD
  8. //
  9. // Adapted for ARC support by Pablo Roca on 20.10.11
  10. //
  11.  
  12. #import "SVProgressHUD.h"
  13. #import <QuartzCore/QuartzCore.h>
  14.  
  15. @interface SVProgressHUD ()
  16.  
  17. @property (nonatomic, readwrite) SVProgressHUDMaskType maskType;
  18. @property (nonatomic, strong) NSTimer *fadeOutTimer;
  19. @property (nonatomic, strong) UILabel *stringLabel;
  20. @property (nonatomic, strong) UIImageView *imageView;
  21. @property (nonatomic, strong) UIActivityIndicatorView *spinnerView;
  22. @property (nonatomic, readonly) CGFloat visibleKeyboardHeight;
  23.  
  24. - (void)showInView:(UIView*)view status:(NSString*)string networkIndicator:(BOOL)show posY:(CGFloat)posY maskType:(SVProgressHUDMaskType)hudMaskType;
  25. - (void)setStatus:(NSString*)string;
  26.  
  27. - (void)dismiss;
  28. - (void)dismissWithStatus:(NSString*)string error:(BOOL)error;
  29. - (void)dismissWithStatus:(NSString*)string error:(BOOL)error afterDelay:(NSTimeInterval)seconds;
  30.  
  31. - (void)memoryWarning:(NSNotification*)notification;
  32.  
  33. @end
  34.  
  35.  
  36. @implementation SVProgressHUD
  37.  
  38. @synthesize maskType, fadeOutTimer, stringLabel, imageView, spinnerView, visibleKeyboardHeight;
  39.  
  40. static SVProgressHUD *sharedView = nil;
  41.  
  42. + (SVProgressHUD*)sharedView {
  43.        
  44.         if(sharedView == nil)
  45.                 sharedView = [[SVProgressHUD alloc] initWithFrame:CGRectZero];
  46.        
  47.         return sharedView;
  48. }
  49.  
  50. + (void)setStatus:(NSString *)string {
  51.         [[SVProgressHUD sharedView] setStatus:string];
  52. }
  53.  
  54.  
  55. #pragma mark - Show Methods
  56.  
  57. + (void)show {
  58.         [SVProgressHUD showInView:nil status:nil];
  59. }
  60.  
  61. + (void)showInView:(UIView*)view {
  62.         [SVProgressHUD showInView:view status:nil];
  63. }
  64.  
  65. + (void)showInView:(UIView*)view status:(NSString*)string {
  66.         [SVProgressHUD showInView:view status:string networkIndicator:SVProgressHUDShowNetworkIndicator];
  67. }
  68.  
  69. + (void)showInView:(UIView*)view status:(NSString*)string networkIndicator:(BOOL)show {
  70.         [SVProgressHUD showInView:view status:string networkIndicator:show posY:-1];
  71. }
  72.  
  73. + (void)showInView:(UIView*)view status:(NSString*)string networkIndicator:(BOOL)show posY:(CGFloat)posY {
  74.     [SVProgressHUD showInView:view status:string networkIndicator:show posY:posY maskType:SVProgressHUDMaskTypeNone];
  75. }
  76.  
  77. + (void)showWithStatus:(NSString *)status {
  78.     [SVProgressHUD showInView:nil status:status];
  79. }
  80.  
  81. + (void)showWithMaskType:(SVProgressHUDMaskType)maskType {
  82.     [SVProgressHUD showInView:nil status:nil networkIndicator:SVProgressHUDShowNetworkIndicator posY:-1 maskType:maskType];
  83. }
  84.  
  85. + (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType {
  86.     [SVProgressHUD showInView:nil status:status networkIndicator:SVProgressHUDShowNetworkIndicator posY:-1 maskType:maskType];
  87. }
  88.  
  89. + (void)showWithStatus:(NSString *)status networkIndicator:(BOOL)show {
  90.     [SVProgressHUD showInView:nil status:status networkIndicator:show];
  91. }
  92.  
  93. + (void)showWithMaskType:(SVProgressHUDMaskType)maskType networkIndicator:(BOOL)show {
  94.     [SVProgressHUD showInView:nil status:nil networkIndicator:show posY:-1 maskType:maskType];
  95. }
  96.  
  97. + (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType networkIndicator:(BOOL)show {
  98.     [SVProgressHUD showInView:nil status:status networkIndicator:show posY:-1 maskType:maskType];
  99. }
  100.  
  101. + (void)showSuccessWithStatus:(NSString *)string {
  102.     [SVProgressHUD show];
  103.     [SVProgressHUD dismissWithSuccess:string afterDelay:1];
  104. }
  105.  
  106.  
  107. #pragma mark - All convenience Show methods get forwarded to this one
  108.  
  109. + (void)showInView:(UIView*)view status:(NSString*)string networkIndicator:(BOOL)show posY:(CGFloat)posY maskType:(SVProgressHUDMaskType)hudMaskType {
  110.     [[SVProgressHUD sharedView] showInView:view status:string networkIndicator:show posY:posY maskType:hudMaskType];
  111. }
  112.  
  113.  
  114. #pragma mark - Dismiss Methods
  115.  
  116. + (void)dismiss {
  117.         [[SVProgressHUD sharedView] dismiss];
  118. }
  119.  
  120. + (void)dismissWithSuccess:(NSString*)successString {
  121.         [[SVProgressHUD sharedView] dismissWithStatus:successString error:NO];
  122. }
  123.  
  124. + (void)dismissWithSuccess:(NSString *)successString afterDelay:(NSTimeInterval)seconds {
  125.     [[SVProgressHUD sharedView] dismissWithStatus:successString error:NO afterDelay:seconds];
  126. }
  127.  
  128. + (void)dismissWithError:(NSString*)errorString {
  129.         [[SVProgressHUD sharedView] dismissWithStatus:errorString error:YES];
  130. }
  131.  
  132. + (void)dismissWithError:(NSString *)errorString afterDelay:(NSTimeInterval)seconds {
  133.     [[SVProgressHUD sharedView] dismissWithStatus:errorString error:YES afterDelay:seconds];
  134. }
  135.  
  136.  
  137. #pragma mark - Instance Methods
  138.  
  139. - (void)dealloc {
  140.        
  141.         if(fadeOutTimer != nil)
  142.                 [fadeOutTimer invalidate], fadeOutTimer = nil;
  143.        
  144.     [[NSNotificationCenter defaultCenter] removeObserver:self];
  145.    
  146. }
  147.  
  148. - (id)initWithFrame:(CGRect)frame {
  149.        
  150.     if ((self = [super initWithFrame:frame])) {
  151.    
  152.                 self.userInteractionEnabled = NO;
  153.         self.backgroundColor = [UIColor clearColor];
  154.                 self.alpha = 0;
  155.        
  156.         self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  157.        
  158.         [[NSNotificationCenter defaultCenter] addObserver:self
  159.                                                  selector:@selector(memoryWarning:)
  160.                                                      name:UIApplicationDidReceiveMemoryWarningNotification
  161.                                                    object:nil];
  162.        
  163.         _hudView = [[UIView alloc] initWithFrame:CGRectZero];
  164.         _hudView.layer.cornerRadius = 10;
  165.                 _hudView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8];
  166.         _hudView.autoresizingMask = (UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin |
  167.                                  UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin);
  168.        
  169.         [self addSubview:_hudView];
  170.        
  171.         [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillHideNotification object:nil queue:nil usingBlock:^(NSNotification *notification) {
  172.             NSDictionary* keyboardInfo = [notification userInfo];
  173.             CGRect keyboardFrame = [[keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
  174.             double animationDuration = [[keyboardInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
  175.             [UIView animateWithDuration:animationDuration delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
  176.                 _hudView.frame = CGRectOffset(_hudView.frame, 0, floor(keyboardFrame.size.height/2));
  177.             } completion:NULL];
  178.         }];
  179.        
  180.         [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:nil usingBlock:^(NSNotification *notification) {
  181.             NSDictionary* keyboardInfo = [notification userInfo];
  182.             CGRect keyboardFrame = [[keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
  183.             double animationDuration = [[keyboardInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
  184.             [UIView animateWithDuration:animationDuration delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
  185.                 _hudView.frame = CGRectOffset(_hudView.frame, 0, 0-floor(keyboardFrame.size.height/2));
  186.             } completion:NULL];
  187.         }];
  188.     }
  189.        
  190.     return self;
  191. }
  192.  
  193. - (void)drawRect:(CGRect)rect {
  194.  
  195.     CGContextRef context = UIGraphicsGetCurrentContext();
  196.    
  197.     switch (self.maskType) {
  198.            
  199.         case SVProgressHUDMaskTypeBlack: {
  200.             [[UIColor colorWithWhite:0 alpha:0.5] set];
  201.             CGContextFillRect(context, self.bounds);
  202.             break;
  203.         }
  204.            
  205.         case SVProgressHUDMaskTypeGradient: {
  206.  
  207.             size_t locationsCount = 2;
  208.             CGFloat locations[2] = {0.0f, 1.0f};
  209.             CGFloat colors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f};
  210.             CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  211.             CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount);
  212.             CGColorSpaceRelease(colorSpace);
  213.            
  214.             CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
  215.             float radius = MIN(self.bounds.size.width , self.bounds.size.height) ;
  216.             CGContextDrawRadialGradient (context, gradient, center, 0, center, radius, kCGGradientDrawsAfterEndLocation);
  217.             CGGradientRelease(gradient);
  218.            
  219.             break;
  220.         }
  221.     }
  222. }
  223.  
  224. - (void)setStatus:(NSString *)string {
  225.        
  226.     CGFloat hudWidth = 100;
  227.     CGFloat hudHeight = 100;
  228.     CGFloat stringWidth = 0;
  229.     CGFloat stringHeight = 0;
  230.     CGRect labelRect = CGRectZero;
  231.    
  232.     if(string) {
  233.         CGSize stringSize = [string sizeWithFont:self.stringLabel.font constrainedToSize:CGSizeMake(200, 300)];
  234.         stringWidth = stringSize.width;
  235.         stringHeight = stringSize.height;
  236.         hudHeight = 80+stringHeight;
  237.        
  238.         if(stringWidth > hudWidth)
  239.             hudWidth = ceil(stringWidth/2)*2;
  240.  
  241.         if(hudHeight > 100) {
  242.             labelRect = CGRectMake(12, 66, hudWidth, stringHeight);
  243.             hudWidth+=24;
  244.         } else {
  245.             hudWidth+=24;  
  246.             labelRect = CGRectMake(0, 66, hudWidth, stringHeight);  
  247.         }
  248.     }
  249.        
  250.         _hudView.bounds = CGRectMake(0, 0, hudWidth, hudHeight);
  251.        
  252.         self.imageView.center = CGPointMake(CGRectGetWidth(_hudView.bounds)/2, 36);
  253.        
  254.         self.stringLabel.hidden = NO;
  255.         self.stringLabel.text = string;
  256.         self.stringLabel.frame = labelRect;
  257.        
  258.         if(string)
  259.                 self.spinnerView.center = CGPointMake(ceil(CGRectGetWidth(_hudView.bounds)/2)+0.5, 40.5);
  260.         else
  261.                 self.spinnerView.center = CGPointMake(ceil(CGRectGetWidth(_hudView.bounds)/2)+0.5, ceil(_hudView.bounds.size.height/2)+0.5);
  262. }
  263.  
  264.  
  265. - (void)showInView:(UIView*)view status:(NSString*)string networkIndicator:(BOOL)show posY:(CGFloat)posY maskType:(SVProgressHUDMaskType)hudMaskType {
  266.        
  267.     BOOL addingToWindow = NO;
  268.    
  269.     if(!view) { // if view isn't specified
  270.         NSArray *keyWindows = [UIApplication sharedApplication].windows;
  271.         UIWindow *keyWindow = [keyWindows lastObject];
  272.         addingToWindow = YES;
  273.        
  274.         if([keyWindow respondsToSelector:@selector(rootViewController)])
  275.             view = keyWindow.rootViewController.view;
  276.        
  277.         if(view == nil)
  278.             view = keyWindow;
  279.     }
  280.        
  281.         if(posY == -1) { // if position isn't specified
  282.         CGFloat activeHeight = CGRectGetHeight(view.bounds);
  283.        
  284.         if(addingToWindow) {
  285.            
  286.             if(self.visibleKeyboardHeight > 0)
  287.                 activeHeight += [UIApplication sharedApplication].statusBarFrame.size.height*2;
  288.            
  289.             activeHeight -= self.visibleKeyboardHeight;
  290.             activeHeight -= view.frame.origin.y;
  291.         }
  292.        
  293.         posY = floor(activeHeight*0.45);
  294.     }
  295.    
  296.         if(fadeOutTimer != nil)
  297.                 [fadeOutTimer invalidate], fadeOutTimer = nil;
  298.        
  299.         [UIApplication sharedApplication].networkActivityIndicatorVisible = show;
  300.        
  301.         self.imageView.hidden = YES;
  302.     self.maskType = hudMaskType;
  303.        
  304.         [self setStatus:string];
  305.         [spinnerView startAnimating];
  306.    
  307.     if(self.maskType != SVProgressHUDMaskTypeNone)
  308.         self.userInteractionEnabled = YES;
  309.     else
  310.         self.userInteractionEnabled = NO;
  311.  
  312.         if(![sharedView isDescendantOfView:view]) {
  313.                 self.alpha = 0;
  314.                 [view addSubview:sharedView];
  315.         }
  316.    
  317.     self.frame = [UIApplication sharedApplication].keyWindow.frame;
  318.        
  319.         if(sharedView.layer.opacity != 1) {
  320.                
  321.         _hudView.center = CGPointMake(CGRectGetWidth(self.superview.bounds)/2, posY);
  322.                 _hudView.layer.transform = CATransform3DScale(CATransform3DMakeTranslation(0, 0, 0), 1.3, 1.3, 1);
  323.                
  324.                 [UIView animateWithDuration:0.15
  325.                                                           delay:0
  326.                                                         options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseOut
  327.                                                  animations:^{ 
  328.                                                          _hudView.layer.transform = CATransform3DScale(CATransform3DMakeTranslation(0, 0, 0), 1, 1, 1);
  329.                              self.alpha = 1;
  330.                                                  }
  331.                                                  completion:NULL];
  332.         }
  333.    
  334.     [self setNeedsDisplay];
  335. }
  336.  
  337.  
  338. - (void)dismissWithStatus:(NSString*)string error:(BOOL)error {
  339.         [self dismissWithStatus:string error:error afterDelay:0.9];
  340. }
  341.  
  342.  
  343. - (void)dismissWithStatus:(NSString *)string error:(BOOL)error afterDelay:(NSTimeInterval)seconds {
  344.    
  345.     if(self.alpha != 1)
  346.         return;
  347.    
  348.     [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
  349.        
  350.         if(error)
  351.                 self.imageView.image = [UIImage imageNamed:@"SVProgressHUD.bundle/error.png"];
  352.         else
  353.                 self.imageView.image = [UIImage imageNamed:@"SVProgressHUD.bundle/success.png"];
  354.        
  355.         self.imageView.hidden = NO;
  356.        
  357.         [self setStatus:string];
  358.        
  359.         [self.spinnerView stopAnimating];
  360.    
  361.         if(fadeOutTimer != nil)
  362.                 [fadeOutTimer invalidate], fadeOutTimer = nil;
  363.        
  364.         fadeOutTimer = [NSTimer scheduledTimerWithTimeInterval:seconds target:self selector:@selector(dismiss) userInfo:nil repeats:NO];
  365. }
  366.  
  367. - (void)dismiss {
  368.        
  369.         [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
  370.        
  371.         [UIView animateWithDuration:0.15
  372.                                                   delay:0
  373.                                                 options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction
  374.                                          animations:^{ 
  375.                                                  _hudView.layer.transform = CATransform3DScale(CATransform3DMakeTranslation(0, 0, 0), 0.8, 0.8, 1.0);
  376.                                                  self.alpha = 0;
  377.                                          }
  378.                                          completion:^(BOOL finished){
  379.                          if(self.alpha == 0) {
  380.                              [self removeFromSuperview];
  381.                          }
  382.                      }];
  383. }
  384.  
  385. #pragma mark - Getters
  386.  
  387. - (UILabel *)stringLabel {
  388.    
  389.     if (stringLabel == nil) {
  390.         stringLabel = [[UILabel alloc] initWithFrame:CGRectZero];
  391.                 stringLabel.textColor = [UIColor whiteColor];
  392.                 stringLabel.backgroundColor = [UIColor clearColor];
  393.                 stringLabel.adjustsFontSizeToFitWidth = YES;
  394.                 stringLabel.textAlignment = UITextAlignmentCenter;
  395.                 stringLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
  396.                 stringLabel.font = [UIFont boldSystemFontOfSize:16];
  397.                 stringLabel.shadowColor = [UIColor blackColor];
  398.                 stringLabel.shadowOffset = CGSizeMake(0, -1);
  399.         stringLabel.numberOfLines = 0;
  400.                 [_hudView addSubview:stringLabel];
  401.     }
  402.    
  403.     return stringLabel;
  404. }
  405.  
  406. - (UIImageView *)imageView {
  407.    
  408.     if (imageView == nil) {
  409.         imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 28, 28)];
  410.                 [_hudView addSubview:imageView];
  411.     }
  412.    
  413.     return imageView;
  414. }
  415.  
  416. - (UIActivityIndicatorView *)spinnerView {
  417.    
  418.     if (spinnerView == nil) {
  419.         spinnerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
  420.                 spinnerView.hidesWhenStopped = YES;
  421.                 spinnerView.bounds = CGRectMake(0, 0, 37, 37);
  422.                 [_hudView addSubview:spinnerView];
  423.     }
  424.    
  425.     return spinnerView;
  426. }
  427.  
  428. - (CGFloat)visibleKeyboardHeight {
  429.     // Locate non-UIWindow.
  430.     UIWindow *keyboardWindow = nil;
  431.     for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
  432.         if (![[testWindow class] isEqual:[UIWindow class]]) {
  433.             keyboardWindow = testWindow;
  434.             break;
  435.         }
  436.     }
  437.    
  438.     // Locate UIKeyboard.  
  439.     UIView *foundKeyboard = nil;
  440.     UIView *tmpKeyboard = nil;
  441.     for (UIView *possibleKeyboard in [keyboardWindow subviews]) {
  442.        
  443.         tmpKeyboard = possibleKeyboard;
  444.                  
  445.         // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView.
  446.         if ([[possibleKeyboard description] hasPrefix:@"<UIPeripheralHostView"]) {
  447.             tmpKeyboard = [[possibleKeyboard subviews] objectAtIndex:0];
  448.         }                                                                                
  449.        
  450.         if ([[tmpKeyboard description] hasPrefix:@"<UIKeyboard"]) {
  451.             foundKeyboard = tmpKeyboard;
  452.             break;
  453.         }
  454.     }
  455.    
  456.     if(foundKeyboard)
  457.         return foundKeyboard.bounds.size.height;
  458.    
  459.     return 0;
  460. }
  461.  
  462. #pragma mark - MemoryWarning
  463.  
  464. - (void)memoryWarning:(NSNotification *)notification {
  465.        
  466.     if (sharedView.superview == nil) {
  467.         [[NSNotificationCenter defaultCenter] removeObserver:self];
  468.         sharedView = nil;
  469.     }
  470. }
  471.  
  472. @end
  473.  
  474.  
RAW Paste Data
Top