2012-11-03 16 views
6

Ho letto e letto su SO di questo, e proprio non riesco a trovare nulla che corrisponda alla mia situazione.Consenti all'utente di annullare MBProgressHUD quando la chiamata JSON impiega troppo tempo

Ho il caricamento di MBProgressHUD quando appare la vista, dato che la mia app va immediatamente ad afferrare alcuni dati del servizio web. Il mio problema è il pulsante Indietro sul mio navigationcontroller non risponde mentre l'HUD è visualizzato (e quindi mentre l'app riceve i suoi dati). Voglio che l'utente sia in grado di toccare per chiudere (o di essere in grado di premere il pulsante indietro nel peggiore dei casi) per ottenere il colpo, se è un'attesa senza fine. Ecco il mio codice che viene eseguito non appena viene visualizzata la vista:

#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 

Tralasciando tutto ciò che non ha senso sull'analisi del JSON. Funziona tutto bene e l'HUD si chiude dopo che i dati appaiono e vengono visualizzati. In che modo nel mondo posso attivare un modo per interrompere tutto questo con un tocco e tornare all'interfaccia (vuota)? GestureRecognizer? Lo avrei impostato nella classe MBProgressHUD? Così frustrato ...

Grazie mille per qualsiasi aiuto. Le mie scuse per il lungo post. E per il mio brutto codice ...

risposta

35

Non c'è bisogno di estendere MBProgressHUD. Basta aggiungere un UITapGestureRecognizer ad esso.

viewDidLoad :

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

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

E poi:

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

Il MBProgressHUD è solo una vista con un disegno personalizzato per indicare il progresso corrente, il che significa che non è responsabile per alcuna logica dell'app. Se hai una lunga operazione che deve essere cancellata ad un certo punto, devi implementarla tu stesso.

La soluzione più elegante è estendere lo MBProgressHUD. Puoi disegnare un'area personalizzata che svolge il ruolo di un pulsante, aggiungere un pulsante a livello di programmazione o semplicemente attendere un evento di tocco sull'intera vista. Quindi puoi chiamare un metodo delegato ogni volta che quel pulsante o la vista viene toccata.

Può assomigliare a questo:

// MBProgressHUD.h 
@protocol MBProgressHUDDelegate <NSObject> 
- (void)hudViewWasTapped; // or any other name 
@end 

// MBProgressHUD.m 
// Either this, or some selector you set up for a gesture recognizer 
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    if ([self.delegate respondsToSelector:@selector(hudViewWasTapped)]) { 
     [self.delegate performSelector:@selector(hudViewWasTapped)]; 
    } 
} 

si devono impostare il controller della vista, come il delegato per la MBProgressHUD e agire di conseguenza.

fatemi sapere se avete bisogno di maggiori chiarimenti su questo :)

+0

Un problema con questo, si chiama anche se genitore vista tocco – Mangesh

0

Per avere informazioni aggiuntive:

  1. È potrebbe creare contentView nella vista
  2. E semplicemente mostrare l'HUD nel contentView (non nella vostra self.view o self.navigationController.view)

in questo modo il vostro punto di vista di navigationBar non sarà responsabile per il tuo hudView. Quindi, puoi tornare indietro dalla tua navigazione, dalla vista del controllore alla pagina precedente.