2010-05-04 18 views
6

Sto cercando di cambiare il controller della vista principale (che appare nel popover in verticale e sul lato sinistro in orizzontale) in un UISplitViewController. Mi piacerebbe passare dal controller della vista principale a uno di due diversi UIViewControllers (a seconda di un'azione intrapresa altrove nella mia applicazione).UISplitViewController non può modificare il controller della vista master?

Sto usando i seguenti:

mySplitViewController.viewControllers = [arrayWithObjects NSArray: newMasterController, detailController, nil];

Questo correttamente cambia il viewcontroller principale come ci si aspetterebbe in modalità orizzontale. Tuttavia, lo non sembra cambiare il viewcontroller utilizzato per il popover in modalità verticale.

Mi accorgo che il comando barbuttonitem per mostrare questo controller della vista master è solo chiamare showMasterInPopover: sul controller splitview, e quindi ci si aspetterebbe che funzioni anche in modalità verticale, ma non è così.

In realtà, è possibile impostare la vista controllore master, vedere la nuova viewController correttamente in modalità orizzontale, ruotare torna al ritratto, e il viewcontroller utilizzato nel popover è ancora quello vecchio.

È un errore?

risposta

1

AGGIORNATO: leggere l'aggiornamento finale in basso! La risposta originale + aggiornamento qui sotto potrebbe non essere utile!

Abbiamo appena avuto esattamente lo stesso problema. A volte mi chiedo se Apple test effettivamente le classi che scrivono con qualcosa che somiglia a casi d'uso realistici, perché UISplitViewController non è il loro momento migliore.

Il problema è che quando si sostituisce il controller della vista principale nella vista divisa, il codice all'interno di UISplitViewController non aggiorna la proprietà contentViewController del controller popover. Il risultato è che il controller popover ha ancora un handle su un controller di visualizzazione non aggiornato, con conseguente visualizzazione di vecchie interfacce utente o persino errori di memoria, quando in modalità verticale.

Ecco la nostra soluzione.

Suppongo che si disponga di una classe conforme UISplitViewControllerDelegate che memorizza popoverController come proprietà di classe (consultare il codice di esempio standard per UISplitViewController).

Al punto in cui si imposta il nuovo controller della vista master, è anche bisogno di aggiornare il contentViewController, come segue:

mySplitViewController.viewControllers 
    = [NSArray arrayWithObjects:newMasterController, detailController, nil]; 

// in the cases where the uisplitview has already shown a popovercontroller, 
// we force the popovercontroller to update its content view controller. 
// This ensures any old content view in popover actually gets released by 
// the popovercontroller. 
if (popoverController) { 
    [popoverController setContentViewController:theMasterViewController 
           animated:NO];  
} 

È inoltre necessario impostare contentViewController del popover quando l'UISplitViewControllerDelegate viene informato che il popover regolatore sta per presentare un controller di vista:

- (void)splitViewController:(UISplitViewController*)svc 
     popoverController:(UIPopoverController*)pc 
     willPresentViewController:(UIViewController *)aViewController 
{ 
    // set the popoverController property - as per Apple's sample code 
    self.popoverController = pc; 

    // THE LINE BELOW IS THE NEW LINE! 
    [popoverController setContentViewController:aViewController animated:NO]; 

Sì, so che il codice di cui sopra sembra folle, e vi state chiedendo perché apple non poteva semplicemente impostare il controller di vista dei contenuti stessi. Ma a quanto pare non lo fanno, e questa è la soluzione.

UPDATE

Lo schema sopra, con l'impostazione della visualizzazione del contenuto, risulta non lavorare dopo tutto. Ad esempio, se si imposta la vista del contenuto come controllore uinavigation, in seguito si passa la vista root all'interno del controller nav, anziché il controller stesso. UISplitViewController semplicemente non gestisce la modifica della vista principale in alcun modo praticabile, per quanto posso vedere.

Per risolvere il problema, è necessario installare un UINavigationController come vista principale e modificare il controller di visualizzazione radice di tale controller di navigazione. Così posso cambiare la vista principale "dalla porta posteriore", in un certo senso.

UPDATE 2

mi arrendo. Anche l'approccio nel primo aggiornamento di cui sopra è imperfetto; Ho ancora problemi con la rotazione. In sostanza, sembra che se si usi UISplitViewController, non si dovrebbe tentare alcuna modifica del controller della vista master (anche se si sta commutando la vista principale quando la vista principale, ad esempio come un popover, è stata nuovamente nascosta). Giocare con il contenuto di un UINavigationController nella vista principale (mentre la vista principale mostra) sembra come se fosse ok, ma tutto ciò che va oltre porta a un problema dopo l'altro. Nota tecnica: ritengo che i problemi derivino da un'apparente debolezza nella gestione delle interfacce utente di Apple: in particolare, il codice Apple chiamerà la release su UIViews e il controller una volta nascosto o rimosso dalla vista, ma poi in seguito, se il viewcontroller contenente è mostrato di nuovo, invia messaggi differiti come viewDidDapparà alle viste/controller rilasciati (che a quel punto potrebbe essere stato deallocato).

+0

Ci sono un sacco di difetti con UISplitViewController. Questo sembra essere uno dei peggiori. Sto ancora vedendo questi problemi come iOS SDK 5.1. Tuttavia, sembra la soluzione alternativa che implica l'utilizzo di un UINavigationController come la vista principale di root funziona in questa versione. –

+0

Wow, ancora così male, questo tardi? Grazie per averci aggiornato Dan. – occulus

2

Nel caso qualcuno è alla ricerca di una soluzione a questo problema (o una parola-around), ho avuto un problema simile e ha lavorato qui: Changing the master view in Split View does not update the popover in portrait

Fondamentalmente, ho usato un controller di navigazione per la vista maestro controller e controller di visualizzazione pushed/poped all'interno di quel controller di navigazione, al fine di cambiare i controller di visualizzazione nella vista master mentre mostra ancora il viewcontroller corretto in orientamento verticale, nella visualizzazione popup.

Problemi correlati