Advertisement
pabloroca

ARC support for SVProgressHUD.m

Oct 19th, 2011
508
0
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.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement