Allow User to Cancel MBProgressHUD when JSON call takes too long

gummo picture gummo · Nov 3, 2012 · Viewed 7.2k times · Source

I've read and read on SO about this, and I just can't seem to find anything that matches my situation.

I've got MBProgressHUD loading when the view appears, as my app immediately goes to grab some webservice data. My problem is the back button on my navigationcontroller is unresponsive while the HUD is displayed (and therefore while the app gets its data). I want the user to be able to tap to dismiss (or to be able to hit the back button in the worst case) to get the heck out, if it's an endless wait. Here's my code that runs as soon as the view appears:

#ifdef __BLOCKS__
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
hud.labelText = @"Loading";
hud.dimBackground = NO;
hud.userInteractionEnabled = YES;

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    // Do a task in the background
    NSString *strURL = @"http://WEBSERVICE_URL_HERE";

    //All the usual stuff to get the data from the service in here

    NSDictionary* responseDict = [json objectForKey:@"data"]; // Get the dictionary
    NSArray* resultsArray = [responseDict objectForKey:@"key"]; 


    // Hide the HUD in the main tread
    dispatch_async(dispatch_get_main_queue(), ^{

        for (NSDictionary* internalDict in resultsArray) 
        {
            for (NSString *key in [internalDict allKeys]) 
            {//Parse everything and display the results
            }

        }

        [MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
    });
}); 
#endif

Leaving out all the gibberish about parsing the JSON. This all works fine, and the HUD dismisses after the data shows up and gets displayed. How in the world can I enable a way to stop all this on a tap and get back to the (blank) interface? GestureRecognizer? Would I set that up in the MBProgressHUD class? So frustrated...

Kindest thanks for any help. My apologies for the long post. And for my ugly code...

Answer

Piotr Tomasik picture Piotr Tomasik · Feb 2, 2013

No need to extend MBProgressHUD. Simply add an UITapGestureRecognizer to it.

ViewDidLoad :

MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:NO];
HUD.mode = MBProgressHUDModeAnnularDeterminate;

UITapGestureRecognizer *HUDSingleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(singleTap:)];
[HUD addGestureRecognizer:HUDSingleTap];

And then:

-(void)singleTap:(UITapGestureRecognizer*)sender
{
      //do what you need.
}