2012-04-20 8 views
6

Ho un po 'di codice da pulire nel mio viewWillDisappear:, che voglio usare solo quando la vista sta tornando al controllore della vista genitore.isBeingDismissed non impostato in viewWillDisappear:

- (void)viewWillDisappear:(BOOL)animated 
{ 
    if ([self isMovingFromParentViewController] || [self isBeingDismissed]) { 
     NSLog(@"isMovingFromParentViewController or isBeingDismissed"); 
     // clean up 
    } 
    [super viewWillDisappear:animated]; 
} 

La vista può essere presentato in due modi: può essere spinto da un controller di navigazione, o presentato come un controller di vista modale (dallo stesso controller di navigazione). Se viene premuto, quindi fatto scoppiare (premendo il pulsante Indietro), il mio codice di pulizia viene eseguito. Se è presentato come un controller di visualizzazione modale, quindi rimosso, il codice non viene eseguito.

mi respingere in questo modo:

[rootViewController dismissModalViewControllerAnimated:YES]; 

La mia domanda è: perché non è isBeingDismissed set quando ho respingere il controller della vista?

risposta

3

Il problema è come si sta ignorando la vista modale. Come viene definito rootViewController?

Quando chiamo [self dismissModalViewControllerAnimated:YES] quindi [self isBeingDismissed] restituisce true.

Quando chiamo [parentViewController dismissModalViewControllerAnimated:YES] quindi [self isBeingDismissed] restituisce true, per cui parentViewController è l'UIViewController che ha presentato la vista modale (nota: non un UINavigationController).

+3

Posso confermare che 'isBeingDismissed() 'restituisce' false' quando il viewController è presumibilmente spuntato da un 'UINavigationController', come il dettaglio viewController in un' UISplitViewController' compresso. – bio

16

Se questo è il primo controller di visualizzazione in un controller di navigazione modale che è stato rimosso, chiamando self.isBeingDimissed() da viewWillDisappear: restituisce false.

Tuttavia, poiché l'intero controller di navigazione è stato rimosso, ciò che effettivamente funziona è self.navigationController?.isBeingDismissed(), che restituisce true.

0
 viewController.isBeingPresented == NO; 
     [rootVC presentViewController:viewController animated:NO completion:^{ 
      viewController.isBeingPresented == NO; 
      viewController.isBeingDismissed == NO; 
      [viewController dismissViewControllerAnimated:NO completion:^{ 
       viewController.isBeingDismissed == NO; 
      }]; 
      viewController.isBeingDismissed == NO; // is not work 
     }]; 
     viewController.isBeingPresented == YES;  // is work 
 viewController.isBeingPresented == NO; 
     [rootVC presentViewController:viewController animated:NO completion:^{ 
      viewController.isBeingPresented == NO; 
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
       viewController.isBeingDismissed == NO; 
       [viewController dismissViewControllerAnimated:NO completion:^{ 
        viewController.isBeingDismissed == NO; 
       }]; 
       viewController.isBeingDismissed == YES; // is work 
      }); 
     }]; 
     viewController.isBeingPresented == YES;  // is work 
2

Come accennato @Yuval Tal, questo flag non funziona quando si sta respingendo regolatore che è embeded all'interno controller di navigazione. Ecco un'estensione che io uso:

extension UIViewController 
{ 
    var isAboutToClose: Bool { 
     return self.isBeingDismissed ||  
       self.isMovingFromParentViewController ||   
       self.navigationController?.isBeingDismissed ?? false 
    } 
} 

Esso può essere facilmente esteso quando si trova un altro caso in cui standard di .isBeingDismissed non funzionerà. E se lo trovi, faccelo sapere nei commenti.

0

Se per caso siete venuti qui cercando di utilizzare isBeingDismissed su un controller non-modale presentato vista, si può sempre controllare la proprietà topViewController del navigationController, per esempio:

if navigationController?.topViewController != self { 
    return 
} 
Problemi correlati