iOS App Dev iOS App Dev - 6 months ago 234
iOS Question

Use of MBProgressHUD Globally + make it singleton

In a Project I each of the user interaction events make a network call (Which is TCP, not HTTP). A 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.

Answer

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;
}