7

Como resumen, tengo problemas con un UINavigationController dentro de un UITabBarController que llama a viewWillAppear cada vez que se saca una vista de la pila.Problemas con UINavigationController dentro de UITabBarController, viewWillAppear no se llama

Desde el delegado, un UITabBarController se hace mediante programación:

// Create views for Tab Bar 
    UINavigationController *view1 = [[UINavigationController alloc] initWithRootViewController:[[newsFeedNavigationController alloc] initWithStyle:UITableViewStylePlain]]; 
    resizedTabBatItem *tabBarItem1 = [[resizedTabBatItem alloc] initWithTitle:nil image:[UIImage imageNamed:@"newspaper.png"] tag:0]; 
    [view1 setTabBarItem:tabBarItem1]; 
    [tabBarItem1 release]; 

    UIViewController *view2 = [UIViewController new]; 
    resizedTabBatItem *tabBarItem2 = [[resizedTabBatItem alloc] initWithTitle:nil image:[UIImage imageNamed:@"speechbubble.png"] tag:1]; 
    [view2 setTabBarItem:tabBarItem2]; 
    [tabBarItem2 release]; 

.... 

// Create the tab bar controller 
    bookTabBarController = [BookTabBarController new]; 
    [[bookTabBarController view] setFrame:CGRectMake(0, 0, 320, 460)]; 

    // Add the views to it 
    NSArray *viewControllers = [NSArray arrayWithObjects:view1, view2, view3, view4, view5, nil]; 

    [[bookTabBarController tabBarController] setViewControllers:viewControllers]; 

Mi newsFeedNavigationController es sólo un UITableViewController subclase (y la subclase no está interfiriendo con viewWillAppear, ya que nunca se le llama en newsFeedNavigationController). En él, los elementos que cuando se hace clic empujarán un nuevo UIViewController en la pila.

El problema es que cada vez que se quitan las vistas de la pila, viewWillAppear nunca se llama en newsFeedNavigationController, y los elementos de la lista permanecen resaltados. He estado jugando con esto por unas horas, estoy en el punto en el que necesito ayuda para saber qué estoy haciendo mal.

En mi newsFeedNavigationController, traté de agregar un NSLog para ver si se llama o hice algo, pero nunca se llama.

- (void)viewWillAppear:(BOOL)animated { 
    NSLog(@"is viewWillAppear called?"); 
    [super viewWillAppear:animated]; 
} 

Editar:

Bien, ahora aquí es algo raro me di cuenta:

Si me quedo:

[self presentModalViewController:(any UIview) animated:YES]; 

y luego descarto que, viewWillAppear comienza a funcionar correctamente cuando aparece y empuja vistas ... Así que ahora estoy perplejo. No es realmente una solución, pero tal vez algo de algo que está sucediendo.

Respuesta

1

Para responder a mi propia pregunta, descubrí cuál era el problema.

Para cumplir con "No UITabBarController dentro de un UINavigationController" de Apple, escribí mi propio controlador de barra de pestañas (bookTabBarController) que está basado en un controlador de vista estándar. Mi problema era que la clase no estaba pasando viewDidAppear a la clase que administraba los controladores de vista, por lo que nunca se supo que se estaba mostrando o no.

+0

Estoy confundido. En tu publicación dijiste "UINavigationController dentro de un UITabBarController" y en tu seguimiento dijiste "UITabBarController dentro de un UINavigationController" ... ¿cuál? Porque estoy teniendo un problema idéntico con un controlador de navegación como una pestaña dentro de un controlador de barra de pestañas ... que, según tengo entendido, debería ser compatible. Pero ViewDidAppear solo comienza a funcionar después de presentar una vista modal desde una de las vistas enviadas al controlador de navegación. Muy extraño. – Steve

+0

Consulte mi respuesta para obtener una solución general a este problema. – titaniumdecoy

+0

Esto fue lo mismo que mi problema. Lo siento por confundir. Lo que inicialmente tenía era un UINavigationController con un controlador de vista, y luego la pantalla de "inicio" contendría lo que esencialmente era un UITabBarController a continuación en la pila. Entonces, podrías empujar una nueva vista en la pila. Ej: UINavigationController con la vista de inicio de sesión como raíz, cuando está insertado, se insertó uitabbar y las vistas de una tabla se pueden insertar en el navegador "principal". Mi problema era que viewWillAppear no se pasaba a la pila (pasaría del UINavigationController al UITabBarController, pero no a la vista de la barra de pestañas). – Dandy

1

Otra solución es configurar el delegado del controlador de navegación. Dentro del delegado, aplicar el siguiente método:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { 
    [viewController viewWillAppear:animated]; 
} 

Esto asegurará que viewWillAppear se llamará en cualquier controlador de vista cuya vista está a punto de aparecer en el control de navegación. Si lo hace de esta manera, se llama aWillAppear independientemente de si la vista está apareciendo porque se está presionando o está apareciendo porque se está sacando una subvista.

+0

Desafortunadamente, probé este método y no funcionó. Bueno, funcionó, pero no funcionó. El problema era que aunque se llamaba a viewWillAppear: animated, no se pasaba a la subvista contenida en la barra de pestañas porque no se llamaba explícitamente en la barra de pestañas viewWillAppear. Pero para otros problemas, esta es una solución potencial. Sin embargo, si viewWillAppear: animated no funciona, probablemente signifique que algo más está mal (como en mi caso). – Dandy

1

Una solución a este problema es hacer que el UIViewController que contiene el UINavigationController le pase los mensajes deseados. El UINavigationController reenviará los mensajes al controlador de vista apropiado. Parece contradictorio, pero funciona.

@interface NavigationWrapperViewController : UIViewController { 
    // navigationController must be a subview of this view controller's view 
    UINavigationController *navigationController; 
} 
@property (nonatomic, assign) UINavigationController *navigationController; 
@end 

@implementation NavigationWrapperViewController 
@synthesize navigationController; 

-(void)viewWillAppear:(BOOL)animated { 
    [navigationController viewWillAppear:animated]; 
} 
-(void)viewDidAppear:(BOOL)animated { 
    [navigationController viewDidAppear:animated]; 
} 
-(void)viewWillDisappear:(BOOL)animated { 
    [navigationController viewWillDisappear:animated]; 
} 
-(void)viewDidDisappear:(BOOL)animated { 
    [navigationController viewDidDisappear:animated]; 
} 

@end

puede encontrar una solución más completa sobre Pastebin (que yo no publicar).

Gracias a davidbenini.it y jaekwon por esta solución.

+0

Esta solución es un poco incompleta y el enlace pegar-bin es un poco un lío sintáctico, pero me condenarán si esto no soluciona mi problema. ¡Rock! –

1

Un truco aún más simple:

En su subclase de UITabBarController, invalidan esto:

-(void)loadView{ 

    [super loadView]; 

    //here goes the trick: 
    [self setSelectedIndex:1]; 
    [self setSelectedIndex:0]; 
} 
+0

Este repaso me ayudó, pero descubrí que volver a poner el índice en 0 inmediatamente no funcionaba. Tuve que esperar hasta viewDidAppear. La otra página no se muestra o parpadea y funciona, porque seleccionar manualmente otra pestaña significaba que la vista problemática funcionaría. Una advertencia es que el índice al que lo configura debe contener una página muy simple. Inicialmente probé una vista con una subvista y la subvista desapareció, pero aún así puede tomar la interacción del usuario, es decir, el problema cambió a esa pestaña. – RowanPD

0

OK, esto es viejo, muy viejo, pero terminó aquí con un problema similar.

UITabViewController 
    UINavigationController 
     UITableViewController1 
     UITableViewController2 

Cuando saliendo de la UITableViewController2, la función viewWillAppear en UITableViewController1 nunca fue llamado.

El problema: Mi clase personalizada UITabViewController estaba anulando viewWillAppear sin llamar a la implementación súper.

Cuestiones relacionadas