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.
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;
}
NOTE...
as with many iOS issues, this is now drastically, totally out of date.
These days you certainly just use a trivial
Container view
for any issue like this.
Full container view tutorial for beginners .. tutorial!
MBProgressHUD was a miraculous solution back in the day, because there was a "drastic hole" in Apple's pipeline.
But (as with many wonderful things from the past), this is only history now. Don't do anything like this today.
Just FWIW, 2014, here's a very simple setup we use. Per David Lawson...
UIWindow *window = [[UIApplication sharedApplication] delegate].window
as Matej says, just use AppDelegate...
#define APP ((AppDelegate *)[[UIApplication sharedApplication] delegate])
AppDelegate.h
// our convenient huddie system (messages with a hud, spinner)
@property (nonatomic, strong) MBProgressHUD *hud;
-(void)huddie;
AppDelegate.m
-(void)huddie
{
// centralised location for MBProgressHUD
[self.hud hide:YES];
UIWindow *windowForHud = [[UIApplication sharedApplication] delegate].window;
self.hud = [MBProgressHUD showHUDAddedTo:windowForHud animated:YES];
self.hud.dimBackground = YES;
self.hud.minShowTime = 0.1;
self.hud.labelText = @"";
self.hud.detailsLabelText = @"";
}
Set the titles in your code where you are using it - because you very often change them during a run. ("Step 1" ... "Step 2" etc)
-(void)loadBlahFromCloud
{
[APP huddie];
APP.hud.labelText = @"Connecting to Parse...";
APP.hud.detailsLabelText = @"step 1/2";
[blah refreshFromCloudThen:
^{
[... example];
}];
}
-(void)example
{
APP.hud.labelText = @"Connecting to the bank...";
APP.hud.detailsLabelText = @"step 2/2";
[blah sendDetailsThen:
^{
[APP.hud hide:YES];
[... showNewDisplay];
}];
}
Change huddle to take the texts as an argument if you wish
You always want self.hud.minShowTime = 0.1; to avoid flicker
Almost always self.hud.dimBackground = YES; which also blocks UI
Conceptually of course you usually have to "slightly wait" to begin work / end work when you bring up such a process, as with any similar programming with the UI.
So in practice code will usually look like this...
-(void)loadActionSheets
{
[APP huddie];
APP.hud.labelText = @"Loading json from net...";
dispatch_after_secs_on_main(0.1 ,
^{
[STUBS refreshNowFromCloudThen:
^{
[APP.hud hide:YES];
dispatch_after_secs_on_main(0.1 , ^{ [self buildActionsheet]; });
}];
}
);
}
Handy macro ..
#define dispatch_after_secs_on_main( SS, BB )
dispatch_after(
dispatch_time(DISPATCH_TIME_NOW, SS*NSEC_PER_SEC),
dispatch_get_main_queue(),
BB
)
This is all history now :) https://stackoverflow.com/a/23403979/294884
This answer is what I've been using for 5-6 Apps now because it works perfectly inside blocks too. However I found a problem with it. I can make it shown, but can't make it disappear if a UIAlertView is also present. If you look at the implementation you can see why. Simply change it to this:
static UIWindow *window;
+ (MBProgressHUD *)showGlobalProgressHUDWithTitle:(NSString *)title {
window = [[[UIApplication sharedApplication] windows] lastObject];
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
hud.labelText = title;
return hud;
}
+ (void)dismissGlobalHUD {
[MBProgressHUD hideHUDForView:window animated:YES];
}
This will make sure you're removing the HUD from the same windows as it was shown on.
链接地址: http://www.djcxy.com/p/87708.html上一篇: 如何在iOS中使用“容器视图”?