7

Ciao a tutti, sono nuovo nello sviluppo di iPhone e non sto capendo l'intera idea di UINavigationController e UITabBarController. È un sostituto per l'altro? In che modo le app come Tweetie combinano entrambe?Avere un UITabBar E un UINavigationController in un'app?

Mi piacerebbe che la mia app avesse una barra delle schede persistente nella parte inferiore (che sembra funzionare), ma anche una barra di navigazione nella parte superiore che può spingere/far apparire le viste sullo schermo senza rimuovere la barra delle schede .

  • Come posso realizzare questo?
  • Quale dovrebbe essere la gerarchia in IB per quanto riguarda il mio MainWindow.xib per quanto riguarda tutti questi controller?
  • Qual è la migliore pratica qui?

Grazie mille,

+3

Direttamente dalla bocca del coder Tweetie: http://stackoverflow.com/questions/576764/tab-bar-controller-inside-a-navigation -controller-or-sharing-a-navigation-root-v – chrissr

risposta

15

Basta posizionare il controller della vista all'interno di UINavigationController e posizionare UINavigationController all'interno di UITabBar. Questo funziona bene per voi ...

Esempio:

NSMutableArray *tabBarViewControllers = [[NSMutableArray alloc] initWithCapacity:2]; 

tabBarController = [[UITabBarController alloc] init]; 
[tabBarController setDelegate:self]; 

UINavigationController *navigationController = nil; 
navigationController = [[UINavigationController alloc] initWithRootViewController:<Your View controller1>]; 
[tabBarViewControllers addObject:navigationController]; 
[navigationController release]; 
navigationController = nil; 

navigationController = [[UINavigationController alloc] initWithRootViewController:<Your View controller2>]; 
[tabBarViewControllers addObject:navigationController]; 
[navigationController release]; 
navigationController = nil; 

tabBarController = tabBarViewControllers; 
[tabBarViewControllers release]; 
tabBarViewControllers = nil; 
+0

Questo ha molto più senso, ogni controller di visualizzazione può avere il proprio controller di navigazione per visualizzare/spingere viste. Grazie! – barfoon

+0

@Manjunath: in questo modo, non riesco a nominare la barra di navigazione e l'elemento della barra delle schede con due nomi diversi. C'è un modo per farlo? – Sefran

3

Utilizzare la procedura guidata per una scheda barra delle applicazioni, e configurarlo come normale. In qualsiasi scheda in cui si desidera aggiungere un controller di navigazione, crearlo in XIB utilizzando la libreria. Il mio XIB ha:

- File's Owner   DescriptiveNameNavViewController 
- First Responder 
- View     UIVIew 
- Navigation Controller UINavigationController 
    - Navigation Bar  UINavigationBar 

Si noti che non c'è nulla nella vista. Vedi viewDidLoad sotto per dove UINavigationController viene collegato a UIView.

Nel file di intestazione per il ViewController della scheda (che ho chiamato DescriptiveNameNavViewController della scheda - non c'è uno standard particolare per questo, ma io uso [Something] NavViewController per ricordarmi che questo ViewController contiene un controller di navigazione con . lo stack di navigazione Questo è il nome del controller che ho impostato nel MainWindow.xib che la procedura guidata genera) Impostare un UINavigationController * IBOutlet che ha il controller di navigazione nel XIB collegato ad esso:

@interface DescriptiveNameNavViewController : UIViewController { 
    UINavigationController *navigationController; 
} 
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; 

@end 

nel controllore per DescriptiveNameNavViewController, fai qualcosa di simile a questo:

L'impostazione del delegato nel DescriptiveNameNavViewController è super-importante, perché altrimenti non si otterranno i metodi chiamati che ci si aspetta nelle istanze DescriptiveNameViewController e qualsiasi altra cosa si inserisca nello stack del controller di navigazione.

In DescriptiveNameNavViewController, implementare i metodi UINavigationControllerDelegate come questo:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated 
{ 
    if ([viewController respondsToSelector:@selector(viewDidAppear:)]) { 
     [viewController viewDidAppear:animated]; 
    } 
} 

E questo modo, i messaggi per ottenere propagati ai controller all'interno del UINavigationController come ci si aspetta. Sembra che molti problemi incontrati dalle persone siano dovuti a viewDidAppear: o altri metodi non vengono richiamati su ViewControllers inseriti nel NavigationController.

In ogni caso, fatemi sapere se ulteriori dettagli potrebbero aiutare.

+0

Ho seguito questo e non funziona. Ancora non ottenendo questo a livello concettuale. Quando lancio l'app e clicco sulla seconda scheda, carica semplicemente la vista e non una con un controller di navigazione. Inoltre, manca il protocollo UINavigationControllerDelegate nella propria intestazione. Perché il navigatore non è definito come IBOutlet nell'interfaccia, ma IS è nella dichiarazione di proprietà? – barfoon

+0

C'è solo un IBOutlet nella dichiarazione @property perché è da lì che viene prelevato dal builder dell'interfaccia. È una macro vuota. Se stai ottenendo una vista vuota sul secondo pannello, è perché il caricamento del Navigation Controller in viewDidLoad non funziona. Ad ogni modo, se la soluzione di chrissr sta funzionando per te, basta osservare i metodi viewWill * e viewDid * che non vengono propagati alle tue subviews e, in tal caso, implementare il delegato. (Il protocollo dei delegati mancante era un mispaste, ma i metodi venivano comunque richiamati). – corprew

Problemi correlati