3

I have an tabbed App using UITabBarController. There are 2 tabs, linked to ViewController1 & ViewController2 respectively. When each view controller loads, it will fetch data from server. Therefore I use MBProgressHUD to show loading status.

However, the behavior currently acts like this: When I switch tab, the app looks like hanged. But after the data is loaded from server, MBProgressHUD flashes a second then disappear, then the view is changed to new tab.

But what I want is: MBProgressHUD shows when the new tab is once touched, and the MBProgressHUD dismisses when the data finishes loading. What did I miss?

Here is the code I use:

- (void)viewDidLoad
{
    [super viewDidLoad];
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.labelText = NSLocalizedString(@"Loading", nil);
    // load data from server, parsing XML, etc
    [MBProgressHUD hideHUDForView:self.view animated:YES];
}

UPDATE: Here I have a sample xCode project , you guys can give it a try and tell me what did I miss. [ Download Link ]

Raptor
  • 53,206
  • 45
  • 230
  • 366

2 Answers2

4

I have had this same issue before. The HUD needs access to the main thread to allow it to show. My guess is you are calling it in a nested method that is blocking out the main thread.

Try calling a method that calls your workload on the main thread. This will present your HUD and dismiss when needed.

[HUD showWhileExecuting:@selector(callingMethod) onTarget:self withObject:nil animated:YES];

-(void)callingMethod {
   [self performSelectorOnMainThread:@selector(dataLoadMethod) withObject:nil waitUntilDone:NO];
}
Bill Burgess
  • 14,054
  • 6
  • 49
  • 86
  • one more thing to add: configure delegate of `MBProgressHUD`. – Raptor Feb 26 '12 at 01:32
  • 1
    You had that code already, so I didn't include it. But yes, you need to configure the HUD before calling -showWhileExecuting. Glad I could help. – Bill Burgess Feb 26 '12 at 15:45
0

See my answer to a similar problem here.

My basic opinion on using MBProgressHUD is to avoid interacting with it within view lifecycle methods and instead use dedicated methods that control just the HUD. For example:

@interface MyViewController : UIViewController

-(void)presentHUDWithText:(NSString *)text;
-(void)dismissHUDWithDelay:(NSTimeInterval)delay; // type name correct? I forget

@end

UIKit is very good about compositing animations together, so that, for example, if you animate a VC push in one line of code, and then immediately in the next cause the HUD to display, it will all look very nice as the VC slides in from the right and the HUD pops up on top of it (you might need to base the HUD in the window to achieve this). Also then, you can present the HUD at the start of your data fetch, and dismiss it at the end. In my experience, data fetches can be very fast, so that the HUD is presented/dismissed too quickly. To compensate for that, I just use an NSTimer to dismiss the HUD after a half second (or whatever feels right).

In short, I'm saying to remove the HUD code from your viewDidLoad above and control it by other means, perhaps by intercepting the tab bar event.

Does this help?

Community
  • 1
  • 1
QED
  • 9,803
  • 7
  • 50
  • 87