2014-09-19 15 views
7

CIRCOSTANZE: iPhone 6 Plus, UISplitViewController rotazione in orizzontale Compatte (compresse) e orizzontali Classi di dimensioni regolari (espanse).Master/dettagli compresso UISplitViewController: rilevamento dettagli View Liquidator controller?

PROBLEMA: Non sembra esserci alcun modo di rilevare - in un crollato UISplitViewController - quando (più a destra, secondaria) View Controller, in cima ad un master (più a sinistra, primario) View Controller, è stato respinto un dettaglio. In un dettaglio View Controller, sia viewWillDisappear: sia viewDidDisappear: riportano sempre NO per isMovingFromParentViewController e isBeingDismissed. UISplitViewControllerviewControllers la proprietà dell'array non è indicativa.

MOTIVO: questo problema è rilevante, perché se un dettaglio View Controller non è contrassegnato come (logicamente) "vuoto" (cioè "cancellato") quando ha respinto, su una successiva espansione UISplitViewController da crollato, un dettaglio View Controller sarà essere ri-mostrato con contenuto potenzialmente (logicamente) irrilevante. Inoltre, quando un espanso UISplitViewController sta collassando, non ha modo di scegliere se presentare solo un controller di visualizzazione master o un controller di visualizzazione dettagli su un controller di visualizzazione principale, tramite il metodo delegato denominato splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:.

risposta

0

Sembra che si stia tentando di consentire alla vista del dettaglio di gestire il contrassegno come "vuoto".

Suggerirei di spostare quella logica sul controller della vista principale, in modo che possa gestire anche altri casi oltre alla rotazione, ad esempio quando arrivano nuovi risultati o l'utente cerca risultati (filtri).

Lascia che il controller della vista principale gestisca l'aggiornamento della vista di dettaglio (contrassegnando i suoi dettagli come nulli, o preferibilmente passandogli nuovi dettagli).

tua vista suddivisa controllore delegato sarà in grado di determinare come gestire il controller di vista secondario, e il codice di controllo dettagliata sarà anche più facile da mantenere, in quanto non hanno conoscenza o sia (strettamente) accoppiato a una fonte di dati.

Aggiornamento:

Non v'è alcun master-solo UISplitViewControllerdisplayMode dove il secondario non può essere mostrato. Le modalità di visualizzazione mostrano tutte il VC secondario, ma possono mostrare, nascondere o sovrapporre il VC primario. L'utente può ruotare il dispositivo, o visualizzare o nascondere il VC primario (tramite presentsWithGesture o displayModeButtonItem), ma il VC secondario verrà sempre visualizzato, vuoto o no, per una classe dimensionale normale.

Ecco come il codice del modello Dettagli principali di Apple determina se il VC secondario deve essere compresso o eliminato, quando il dispositivo passa a una classe di dimensioni orizzontalmente compatta.

- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController { 
    if ([secondaryViewController isKindOfClass:[UINavigationController class]] && [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[YHWHDetailViewController class]] && ([(YHWHDetailViewController *)[(UINavigationController *)secondaryViewController topViewController] detailItem] == nil)) { 
     // Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded. 
     return YES; 
    } else { 
     return NO; 
    } 
} 

Nota che Apple utilizza una proprietà sul controller dettaglio vista come una bandiera.

ho capito si ritiene che la decisione se il VC secondario dovrebbe essere crollato o scartato dovrebbe essere basata sul fatto che l'utente ha respinto esplicitamente la VC secondario (mentre è crollato in una dimensione orizzontale compatta).

Capisco che si sta cercando di rendere dettaglio VC "chiaro" per sé quando scompare, ma assumendo che è stato respinto (scartato) e non si è in possesso di un forte riferimento ad essa, che sarebbe un non- operazione.

È più semplice se il dettaglio scompare (oppure lo dataSource annulla i dettagli).

Se si sta tenendo su di esso, e non si può cancellare i dettagli, potrete sia necessario per:

  • mantenere un po 'tipo di bandiera (se un oggetto BOOL o nullo) che riflette se il contenuto del dettaglio è stato reso "irrilevante" e si basa su tale flag per determinare in futuro se il controller della vista secondaria debba (ancora una volta) essere compresso o meno.
  • Controllare il dettaglio (prima di richiuderlo di nuovo) contro dataSource per vedere se il contenuto è "rilevante" o "irrilevante".

Se si utilizza una proprietà VC di dettaglio come bandiera, ecco il vantaggio. Quando l'SVC è compresso, e il dettaglio VC è stato "espressamente chiuso", non c'è più un VC secondario da dividere dal VC primario.

- (UIViewController *)splitViewController:(UISplitViewController *)splitViewController 
separateSecondaryViewControllerFromPrimaryViewController:(UIViewController *)primaryViewController{ 

    if ([primaryViewController isKindOfClass:[UINavigationController class]]) { 
     for (UIViewController *controller in [(UINavigationController *)primaryViewController viewControllers]) { 
      if ([controller isKindOfClass:[UINavigationController class]] && [[(UINavigationController *)controller visibleViewController] isKindOfClass:[DetailViewController class]]) { 
       return controller; 
      } 
     } 
    } 

    // No detail view present 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; 
    UINavigationController *secondaryViewController = [storyboard instantiateViewControllerWithIdentifier:@"SecondaryViewController"]; 

    // Ensure back button is enabled 
    UIViewController *detailViewController = [secondaryViewController visibleViewController]; 
    detailViewController.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem; 
    detailViewController.navigationItem.leftItemsSupplementBackButton = YES; 

    return secondaryViewController; 

} 

Perché si crea un'istanza di un dettaglio "vuoto" VC, quando l'utente ruota lo SVC ritorno da dimensioni regolari a dimensioni compatte, il delegato SVC può vedere che non ci sono dettagli da visualizzare, in modo di annullare il VC secondaria .

Questo è l'approccio di Apple, e funziona molto bene, perché lascia il controllo sul fatto che SVC sia compresso o espanso all'utente, tramite una rotazione, un gesto o il pulsante della modalità di visualizzazione.

Sono sicuro che hai visto l'app di posta Apple sul 6 Plus. Nota, però, di ciò che Apple fa una volta che l'utente ruota di nuovo a una classe dimensionale normale. Anche se l'utente torna all'elenco dei messaggi, il messaggio selezionato in precedenza viene comunque visualizzato quando ricompare il dettaglio.

Se è possibile rendere la vostra app si comporta anche in questo modo, lo incoraggerei. È amichevole, conveniente e gratificante, perché risparmia all'utente il tempo di dover effettuare una (ri) selezione e mostra dettagli invece di una vista vuota.

+0

Un controller di visualizzazione master non sa se è di nuovo visualizzato perché un dettaglio View Controller viene eliminato (la classe di dimensioni Compact orizzontale, compresso) o perché un figlio di un dettaglio View Controller viene eliminato (le dimensioni orizzontali normali) classe, side-by-side). Pertanto, un master VC non può sapere quando contrassegnare un dettaglio VC come vuoto. Inoltre, questo tipo di soluzione creerebbe un accoppiamento stretto tra una particolare classe di un VC master con una particolare classe di un VC di dettaglio, che è probabilmente peggiore della conoscenza del livello del modello di dominio (un'origine dati). – Gary

+0

Vedo il tuo punto, ma non sono d'accordo che "se un VC secondario dovrebbe essere [nascosto] o [cancellato] dipende dal fatto che il dettaglio abbia contenuti da mostrare". Nello stato compresso, l'attivazione e l'animazione del licenziamento secondario VC sono identiche al licenziamento VC non splitter, pertanto ritengo che dovrebbe sempre invalidare i contenuti VC secondari. *** Credo che un master VC e un dettaglio VC dovrebbero essere disaccoppiati: un VC master notifica un modello di dominio di una particolare condizione di filtraggio dei dati e un dettaglio VC viene notificato da un modello di dominio che deve essere aggiornato (nessun messaggio diretto tra un master VC e un dettaglio VC). – Gary

+0

Grazie per il suggerimento, ma in caso di 'collapseSecondaryViewController: ontoPrimaryViewController:' è lo stesso problema di nuovo: il delegato non ha modo di sapere se un dettaglio VC è stato precedentemente espressamente rifiutato da un utente, o no, quindi non può mai decidere di nascondere il VC secondario. Voglio scartare SOLO contenuti VC secondari se è stato esplicitamente "abbandonato" da un utente, che non vuole vederlo più ed esplicitamente VAI INDIETRO ad un VC master. La rotazione da sola non dovrebbe mai influire sul contenuto (scartare). – Gary

0

Quando l'iPhone passa dal display collassato a quello espanso (cioè da verticale a orizzontale), il master riceve una chiamata allo -viewWillAppear:. Qui puoi decidere di mostrare un viewcontroller di dettaglio vuoto o uno "valido" popolato, dipendente da ciò che è selezionato nel master (o niente selezionato affatto), e da questo scarti qualsiasi viewcontroller di dettagli precedentemente visualizzato con dati potenzialmente non validi.

Ma non vedo come un viewcontroller di dettaglio, in una transizione espansa a compresso, dovrebbe mostrare contenuto irrilevante. Anche se il master è invisibile è ancora intatto, e così dovrebbe essere il viewcontroller di dettaglio.

+0

'viewWillAppear:' in un controller di master View non risolutivo, si prega di consultare il primo commento sotto la risposta di PetahChristian: "Un controller di visualizzazione master non sa se è riapparso perché un dettaglio View Controller viene eliminato (la classe di dimensioni Compact orizzontalmente , collassato) o perché un figlio di un particolare View Controller viene eliminato (la classe di dimensioni Regular orizzontalmente, affiancata). " – Gary

+0

Un esempio di dettaglio View Controller che mostra contenuto irrilevante è una quotazione azionaria time-sensitive, una transazione finanziaria in corso o qualsiasi informazione di sicurezza sensibile. Nel momento in cui un dettaglio View Controller viene eliminato, dovrebbe essere esplicitamente cancellato e le informazioni (annullate) non dovrebbero mai magicamente riapparire solo perché un dispositivo è stato ruotato. – Gary

+0

Penso che un UISplitViewController potrebbe non essere l'interfaccia utente di scelta se si desidera che il dettaglio venga ignorato ed evitare la sua ricomparsa durante la rotazione. Il master dovrebbe essere visto come una vista opzionale, anche in una disposizione collassata. – bio

Problemi correlati