I'm displaying some views,webVies and while they are loading i display an ProgressHud with waiting message. I'm using an instance of that object :
MBProgressHUD * progrssHUD
Using the show and hide methods to control over loading windows. In some views i would like to add view only after the hide method is turned on - meaning no window displayed now.
How can i check from any interface what is that status of MBProgressHUD and only after status X to do something?
If you see the implementation of MBProgresshud then you will find that when they are hiding it they are setting it's alpha 0 and when they are showing it they are setting it alpha 1.
So you can use this property to check whether it is hidden or shown.
i.e
if(progrssHUD.alpha == 0){
//perform hide operation
}else{
//Perform show operation
}
-(IBAction)SHOW{
HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
[self.navigationController.view addSubview:HUD];
HUD.delegate = self;
[HUD show:YES];
// Show the HUD while the provided method executes in a new thread
[HUD showWhileExecuting:#selector(showHUD) onTarget:self withObject:nil animated:YES];
}
- (void)hudWasHidden:(MBProgressHUD *)hud {
// Remove HUD from screen when the HUD was hidded
[HUD removeFromSuperview];
[HUD release];
HUD = nil;
}
THE METHOD showWhileExecuting CALLING THE HUD WAS ACTIVE WHILE THE DELEGATE METHOD WILL COME.
Related
MPProgressView won't display when I try to push a viewcontroller until seconds before the pushed VC is displayed. Should the viewController be placed in the same function as the MBProgressView is displayed? I've made sure that my MBProgressView is on the main thread, I've tried many solutions on SO and can't see anyone with the same issue. I am simply trying to display the MBProgressHUD while the viewController is loading and being pushed. Thanks!
I am using MBProgressView as follows:
- (IBAction)pushButton:(id)sender
{
self.HUD =[MBProgressHUD showHUDAddedTo:self.view animated:YES];
[self.view addSubview:self.HUD];
self.HUD.labelText = #"Doing stuff...";
self.HUD.detailsLabelText = #"Just relax";
self.HUD.delegate=self;
[self.view addSubview:self.HUD];
[self.HUD showWhileExecuting:#selector(loadCreate) onTarget:self withObject:nil animated:YES];
}
- (void)loadCreate {
[self performSelectorOnMainThread:#selector(dataLoadMethodMail) withObject:nil waitUntilDone:YES];
}
-(void)dataLoadMethodMail
{NSLog(#"data load method is displaying");
SelectViewController *mvc = [[SelectViewController alloc] init];
[self.navigationController pushViewController:mvc animated:YES];
}
You don't need to add self.HUD to self.view, showHUDAddedTo: does it for you.
[self.HUD showWhileExecuting:#selector(loadCreate) onTarget:self withObject:nil animated:YES];
Shows the hud until loadCreate returns.
[self performSelectorOnMainThread:#selector(dataLoadMethodMail) withObject:nil waitUntilDone:YES];
dispatches something on main thread and returns right after (before the actual end of dataLoadMethodMail). The HUD is shown but disappears right away.
To solve the issue try hiding manually the HUD when dataLoadMethodMail finishes it's work.
Just replace
[self.HUD showWhileExecuting:#selector(loadCreate) onTarget:self withObject:nil animated:YES];
with
[self loadCreate];
and add
dispatch_async(dispatch_get_main_queue(), ^{
[self.HUD hide:YES];
});
at the end of dataLoadMethodMail
PS : Loading data should not be done on main thread.
First time working with a HUD and I'm confused.
I setup the HUD like this in my viewDidLoad:
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[[[WSXmppUserManager shared] xmppStreamManager] connect];
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
});
The HUD doesn't show. I think the reason is as follows. The xmpp connect method fires off a connection request to the xmpp server and then it's done. So there is no activity to wait for as is.
However, the connection isn't established until the server responds and the following delegate method is fired:
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
I want to wait for this and only then dismiss the HUD, but I'm at a loss as to how to do that. I'm missing something very simple.
You need to move this code
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
After your long running method has finished... that is, if this code is indeed returning immediately
[[WSXmppUserManager shared] xmppStreamManager] connect];
The hud is likely never going to display... as it gets told to display and then told to hide on the same run loop or perhaps one run loop right afterwards...
Why not put it at the end of this method if this indicates that a response has been received and the operation is completed?
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
HUD =[[MBProgressHUD alloc] initWithWindow:self.view];
[HUD setDelegate:self];
[self.view addSubview:HUD];
[HUD showWhileExecuting:#selector(connectToServer)
onTarget:self
withObject:nil
animated:YES];
In the connectToServer
-(void)connectToServer
{
[[[WSXmppUserManager shared] xmppStreamManager] connect];
}
As soon as the connectToServer method comepletes it task in the background , a delegate of MBProgressHUD called hudWasHidden: is automatically called
-(void)hudWasHidden:(MBProgressHUD *)hud
{
//Further work after the background task completed
}
In the viewDidload method, i am using MBProgressHUD to show an activity indicator until data is downloaded from the net, and thereafter to check if the application has enabled GPS. based on this i alert the user using MBProgressHUD.
My code;
ViewDidLoad
hudForDownloadData = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
[self.navigationController.view hudForDownloadData ];
hudForDownloadData .delegate = self;
hudForDownloadData .labelText = #"Loading";
hudForDownloadData .detailsLabelText = #"updating data";
[hudForDownloadData showWhileExecuting:#selector(downloadDataFromWebService) onTarget:self withObject:nil animated:YES];
[self downloadDataFromWebService]; // This method is called, and then data is downloaded from the webservice, once the data is downloaded i will remove the `MBProgressHUD ` alert
Now i am checking if the application has enabled access to GPS, and alert the user if not.
hudForGPS = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
[self.navigationController.view addSubview:HUD];
hudForGPS .delegate = self;
hudForGPS .labelText = #"Loading";
hudForGPS .detailsLabelText = #"updating data";
[hudForGPS showWhileExecuting:#selector(checkIfApplicationEnabledGPS)
onTarget:self withObject:nil animated:YES]; // This will only take a
maximum of 2-3 seconds. and i will remove it after that
The problem is that; when the internet/wifi is down, the hudForDownloadData will continuously animate (display uiactivityindicator). In the meantime hudForGPS will also execute. But it will display below hudForDownloadData . So the user will not be able to see it.
What i want to do is to execute the checkIfApplicationEnabledGPS first, and wait till its alert finishes (it will only take 2-3 seconds), and then load execute the downloadDataFromWebService where if the internet/wifi is not available it will display forever.
How can i do this programatically ?
Execute checkIfApplicationEnabledGPS first and when it is finished,you show an alert box,If you are using UiAlertView to show the alert then you can handle it's delegate:-
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
when the user presses ok button in UiAlert view you can override the above delegate with hudForDownloadData
In this way both the checkIfApplicationEnabledGPS and hudForDownloadData will be executed one after the other
I'm having an issue with my save button in a modal UINavController. When I press the save button, I'm dismissing the keyboard if it is still up, validating the data from the text fields, then showing a UIProgressView while I send my info out.
My problem is that the keyboard isn't getting out of the way fast enough, so keyboard is still up when it is time to show the UIProgressView and it is getting added towards the bottom of my view and it looks stupid.
I can hit the return key, and the keyboard drops, then press save, no issues. But if the user skips the keyboard return key and goes right for the top right save button, I have issues.
Ideally I'd like to implement a short wait statement for it to drop out of sight. Or perform my validation after a delay, but nothing I have tried is working. Please help.
Code Example:
// end edit mode - should kill all keyboards
[[self.tableView superview] endEditing:YES];
// make sure everything is entered correctly and validates
[self validateEntryFields]; // keyboard not gone when this finishes
if (valid) { // progress view shows up towards bottom of view
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = #"Adding User";
HUD.detailsLabelText = #"Please Wait";
[HUD showWhileExecuting:#selector(sendNewUserInformation) onTarget:self withObject:nil animated:YES];
}
You may use keyboard notification (it would be more correct solution than based on timer):
[notificationCenter addObserver: self selector: #selector(keyboardDidHide:) name: UIKeyboardDidHideNotification object: nil];
And show your progress view in keyboardDidHide: method.
If a small delay would be working you could try the following code between your validation and your if statement where you decide whether or not you will showing the progress view.
You can use the NSTimer object:
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(mumboJumbo:)userInfo:nil repeats:NO];
And add your code into a method like:
-(void)mumboJumbo:(id)sender{
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = #"Adding User";
HUD.detailsLabelText = #"Please Wait";
[HUD showWhileExecuting:#selector(sendNewUserInformation) onTarget:self withObject:nil animated:YES];
}
If I understood correctly your problem that should work.
I've got both working great individually, but when I try to combine them like this:
- (IBAction)showWithLabel:(id)sender
{
HUD = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
[self.checkinsViewController.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = #"Sending tweet";
[HUD showWhileExecuting:#selector(tweet) onTarget:self withObject:nil animated:YES];
}
- (void)tweet { [_twEngine sendUpdate:#"Test tweet"]; }
I don't get any errors, but the tweet isn't sent If I place:
[_twEngine sendUpdate:#"Test tweet"];
In the IBAction, it tweets. If I change tweet to sleep, the HUD shows up properly.
Any ideas?
The showHUDAddedTo:animated: and showWhileExecuting: methods are mutually exclusive. You can't use both methods to show the HUD .
Change your initializer to just allocate a HUD and it should work.
HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];