iphoneiossingletonmbprogresshud

Use of MBProgressHUD Globally + make it singleton


In my Project, each of the user interaction events make a network call (Which is TCP, not HTTP). I need Activity Indicator to be global to show from a random UIViewController and hide from NetworkActivityManager Class (a custom class to handle network activities, Which is not a subclass of UIViewController or UIView).

After searching the web I found out that MBProgressHUD is used for the same purpose, but I wasn't able to find out an example on how would I use it globally. (By saying global I mean a singleton object of MBProgressHUD and class methods to SHOW and HIDE it.)

Following is what I have tried yet, but, failed: In AppDelegate.h:

@property (nonatomic, retain) MBProgressHUD *hud;

In AppDelegate.m:

@synthesize hud;

In some random UIViewController object:

appDelegate.hud = [MBProgressHUD showHUDAddedTo:appDelegate.navigationController.topViewController.view animated:YES];
appDelegate.hud.labelText = @"This will take some time.";

And while hiding it, from NetworkActivityManager Class:

[MBProgressHUD hideHUDForView:appDelegate.navigationController.topViewController.view animated:YES];

This makes the project to crash after some time (due to memory issues.) I am using ARC in my project and also, I am using the ARC version of MBProgressHUD.

Am I missing something?

Important Question:

Can I make MBProgressHUD work like UIAlertView? (Saying that I mean implementation of MBProgressHUD independent of UIView -- sa it uses showHUDAddedTo: to present itself) ???

Please Note: In the above code of hiding MBProgressHUD, View may be changed from what it was when showing MBProgressHUD.

Any Help greatly appreciated.


Solution

  • You could add this to a class of your liking:

    + (MBProgressHUD *)showGlobalProgressHUDWithTitle:(NSString *)title {
        UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];
        MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
        hud.labelText = title;
        return hud;
    }
    
    + (void)dismissGlobalHUD {
        UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];
        [MBProgressHUD hideHUDForView:window animated:YES];
    }
    

    This can be than called on any class. You don't need to keep a strong reference to the HUD when using those class convenience methods.

    Depending on your specific situation you'll probably also want to handle cases where a new hud is requested before the other one is hidden. You could eater hide the previous hud when a new comes in or come up with some sort of queueing, etc.

    Hiding the previous HUD instance before showing a new one is pretty straightforward.

    + (MBProgressHUD *)showGlobalProgressHUDWithTitle:(NSString *)title {
        UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];
        [MBProgressHUD hideAllHUDsForView:window animated:YES];
        MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
        hud.labelText = title;
        return hud;
    }