7

Hola a todos, soy nuevo en el desarrollo de iPhone y no entiendo toda la idea de UINavigationController y UITabBarController. ¿Es uno un sustituto del otro? ¿Cómo combinan ambas aplicaciones, como Tweetie?Tener un UITabBAR Y un UINavigationController en una aplicación?

Me gustaría que mi aplicación tenga una barra de pestañas persistente en la parte inferior (que parece funcionar), pero también una barra de navegación en la parte superior que puede insertar/mostrar vistas en la pantalla sin quitar la barra de pestañas .

  • ¿Cómo puedo lograr esto?
  • ¿Cómo debería ser la jerarquía en IB en cuanto a mi MainWindow.xib con respecto a todos estos controladores?
  • ¿Cuál es la mejor práctica aquí?

Muchas gracias,

+3

directamente de la boca del codificador Tweetie: http://stackoverflow.com/questions/576764/tab-bar-controller-inside-a-navigation -controller-or-sharing-a-navigation-root-v – chrissr

Respuesta

15

Simplemente ajuste el controlador de visualización dentro de UINavigationController y Coloque el UINavigationController dentro del UITabBar. Esto funciona bien para usted ...

Ejemplo:

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

Esto tiene mucho más sentido, cada controlador de vista puede tener su propio controlador de navegación para mostrar/mostrar vistas. ¡Gracias! – barfoon

+0

@Manjunath: de esta manera, no logro nombrar la barra de navegación y el elemento de la barra de pestañas con dos nombres diferentes. ¿Hay una manera de hacer eso? – Sefran

3

utiliza el asistente para una barra de aplicaciones Tab y configurarlo como normal. En cualquier pestaña donde desee agregar un controlador de navegación, créelo en el XIB utilizando la biblioteca. Mi XIB tiene:

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

Tenga en cuenta que no hay nada en la vista. Consulte viewDidLoad a continuación para ver dónde se conecta el UINavigationController a UIView.

En el archivo de encabezado para ViewController de la pestaña (que aquí he llamado DescriptiveNameNavViewController - no hay un estándar particular para esto, pero utilizo [Something] NavViewController para recordarme que este ViewController contiene un controlador de navegación con . la pila de navegación Este es el nombre del controlador que puse en el MainWindow.xib que el asistente genera) Establecer un UINavigationController * IBOutlet que tiene el control de navegación en el XI ter que se le atribuye:

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

@end 

en el controlador para el DescriptiveNameNavViewController, haga algo como esto:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [[self view] addSubview:[navigationController view]]; 
    DescriptiveNameController *aController = [[[DescriptiveNameController alloc ] initWithNibName:@"DescriptiveNameController" bundle:nil ] autorelease]; 
    aController.title = @"Descriptive Title"; 

// 
// app stuff goes here. 
// 

    [self.navigationController pushViewController:aController animated:YES]; 
    [self.navigationController setDelegate:self]; 
} 

Configurar el delegado en el DescriptiveNameNavViewController es muy importante, porque de lo contrario no obtendrá los métodos llamados que espera en las instancias de DescriptiveNameViewController y cualquier otra cosa que inserte en la pila del controlador de navegación.

En DescriptiveNameNavViewController, poner en práctica los métodos UINavigationControllerDelegate como este:

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

Y eso va a hacer que los mensajes consiguen propagan a los controladores dentro de la UINavigationController como se esperaba. Parece que muchos de los problemas que encuentran las personas se deben a que viewDidAppear: u otros métodos no se invocan en ViewControllers insertados en NavigationController.

De todos modos, avíseme si más detalle ayudaría.

+0

He seguido esto y no funciona. Aún no obtengo esto a nivel conceptual. Cuando abro la aplicación y hago clic en la segunda pestaña, simplemente carga la vista, y no una con un controlador de navegación. Además, le falta el protocolo UINavigationControllerDelegate en su encabezado. ¿Por qué no se define navigationController como IBOutlet en la interfaz, sino que IS está en la declaración de propiedad? – barfoon

+0

Solo hay un IBOutlet en la declaración @property porque el creador de interfaces lo recoge. Es una macro vacía. Si obtiene una vista vacía en el segundo panel, es porque cargar el Controlador de navegación en viewDidLoad no funciona. En cualquier caso, si la solución de chrissr está funcionando para usted, simplemente observe que los métodos viewWill * y viewDid * no se propaguen a sus subvistas y, de ser así, implemente el delegado. (El protocolo de delegado faltante era un error, pero los métodos se llamarían de todos modos). – corprew

Cuestiones relacionadas