2013-07-05 7 views
6

Ciao Sto lavorando su un'app per iPad e ho ottenuto il requisito di respingere tutti i popover (se presenti) quando l'app va in background.Ignora popover quando l'app per iPad va in background

Ho fatto qualche studio online e non ho trovato un modo semplice per farlo. Mi piacerebbe condividere una mia idea qui e vedere se c'è un modo migliore per farlo.

1, Eliminare i popover in didEnterBakcground in delegato. Sembra non pratico dal momento che dobbiamo aggiungere tutti popovers riferimento.

2, Passare attraverso tutte le viste in modo ricorsivo nella finestra corrente per trovare vista popover da (class = _UIPopoverView). Sembra un po 'hacky e pericoloso.

3, Impostare UIApplicationDidEnterBackgroundNotificationgroundNotification in ogni oggetto che possiede i popover e li congeda. Questo sembra ragionevole, ma davvero problematico se ci sono centinaia di popover nella tua app.

4, come su aggiungere un metodo di categoria dire - (void) dismissWhenAppWillEnterBackground; e registrare la notifica.

O c'è un modo più semplice per farlo?

+2

Perché dovresti avere centinaia di popup nella tua app? Basta impostare i pop pop attivi per osservare UIApplicationDidEnterBackgroundNotificationgroundNotification o l'equivalente di willEnterBackground e farli ignorare. – Jessedc

+0

@Jessedc È affari ha bisogno di avere quei popover. Voglio solo vedere se c'è una soluzione migliore di questa. Grazie. – ThinkChris

risposta

9

Ecco una categoria drop-in su UIPopoverController che fa ciò che stai chiedendo.

Fondamentalmente le swizzles categoria initWithContentViewController: in modo che possa monitorare in tempo reale UIPopoverController casi in un NSHashTable (che non si detengono i UIPopoverControllers contenute vivi poiché mantiene riferimenti deboli a loro.) Essa controlla anche per UIApplicationDidEnterBackgroundNotification, e quando questo arriva itera la collezione di UIPopoverControllers live e congela quelli che stanno mostrando.

Potrebbe essere utile estendere questo per implementare la regola "non consentire mai a due popover di mostrare contemporaneamente" quella di Apple.

Io non sono un grande fan del metodo di swizzling nelle app di produzione, ma questo sembra abbastanza sicuro.

Nessuna istruzione speciale per l'uso. Basta includere la categoria nel tuo progetto e utilizzare normalmente i tuoi UIPopoverControllers.

#import <objc/runtime.h> 

@interface UIPopoverController (autodismiss) 
@end 

@implementation UIPopoverController (autodismiss) 

static NSHashTable* ts_popoverHashTable; 

+ (void) load 
{ 
    SEL originalSelector = @selector(initWithContentViewController:); 
    SEL replacementSelector = @selector(ts_initWithContentViewController:); 
    Method originalMethod = class_getInstanceMethod([UIPopoverController class], originalSelector); 
    Method replacementMethod = class_getInstanceMethod([UIPopoverController class], replacementSelector); 
    method_exchangeImplementations(originalMethod, replacementMethod); 

    [[NSNotificationCenter defaultCenter] addObserver: self 
              selector: @selector(applicationDidEnterBackgroundNotification:) 
               name: UIApplicationDidEnterBackgroundNotification 
               object: nil]; 
} 

- (id) ts_initWithContentViewController: (UIViewController*) contentViewController 
{ 
    UIPopoverController* pc = [self ts_initWithContentViewController: contentViewController]; 

    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 

     ts_popoverHashTable = [NSHashTable weakObjectsHashTable]; 
    }); 

    [ts_popoverHashTable addObject: pc]; 

    return pc; 
} 

+ (void) applicationDidEnterBackgroundNotification: (NSNotification*) n 
{ 
    for (UIPopoverController* pc in ts_popoverHashTable) 
    { 
     if (pc.isPopoverVisible) 
     { 
      [pc dismissPopoverAnimated: NO]; 
     } 
    } 
} 

@end 
2

Scrivi un protocollo con un paio di metodi opzionali:

- (void)appWillEnterBackground; 
- (void)appWillBecomeActive; 

Fai i controller di vista per applicarla e poi nella vostra applicazione delegato, accedere vostro controller della vista principale, verificare se risponde a questi metodi e invocare quando l'app diventa di base e diventa attiva. Dovresti essere in grado di ottenere facilmente il controller di visualizzazione radice. Se si dispone di una gerarchia di controller di vista, potrebbe essere necessario inoltrare la chiamata.

Aggiungi il tuo codice di licenziamento popover in appWillEnterBackground, per esempio.

3

io possa avere una risposta migliore, che è aggiungere un metodo categoria - (void) dismissWhenAppWillEnterBackground per UIPopoverController e registrare UIApplicationWillEnterBackgroundNotificationgroundNotification.

2
  1. Creare una classe base UIViewController per tutti i controller di vista nell'applicazione.
  2. Aggiungere un array che contiene i riferimenti alle visualizzazioni popover nel particolare controller di vista
  3. Mantenere un riferimento al delegato di app iin di viewcontroller corrente.
  4. Quando l'app entra in background, recupera il viewcontroller corrente e attraversa l'array popover e chiude tutti i popover.
Problemi correlati