iPhone oculta la barra de navigation solo en la primera página

Tengo el código a continuación que se esconde y muestra la barra de navigation. Está oculto cuando la primera vista se carga y luego se oculta cuando los "niños" son llamados. El problema es que no puedo encontrar el evento / acción para activarlo para ocultarlo nuevamente cuando vuelven a la vista raíz …

Tengo un button de "testing" en la página raíz que hace la acción manualmente, pero no es bonito y quiero que sea automático.

-(void)hideBar { self.navController.navigationBarHidden = YES; } -(void)showBar { self.navController.navigationBarHidden = NO; } 

La mejor solución que he encontrado es hacer lo siguiente en el primer controller de vista .

C objective

 - (void)viewWillAppear:(BOOL)animated { [self.navigationController setNavigationBarHidden:YES animated:animated]; [super viewWillAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { [self.navigationController setNavigationBarHidden:NO animated:animated]; [super viewWillDisappear:animated]; } 

Rápido

 override func viewWillAppear(animated: Bool) { self.navigationController?.setNavigationBarHidden(true, animated: animated) super.viewWillAppear(animated) } override func viewWillDisappear(animated: Bool) { self.navigationController?.setNavigationBarHidden(false, animated: animated) super.viewWillDisappear(animated) } 

Esto hará que la barra de navigation se active desde la izquierda (junto con la siguiente vista) cuando presiona el siguiente UIViewController en la stack y se anima hacia la izquierda (junto con la vista anterior) cuando presiona el button Atrás el UINavigationBar .

Tenga en count también que estos no son methods delegates, UIViewController la implementación de estos methods por parte de UIViewController , y de acuerdo con la documentation debe llamar a la implementación del super en algún lugar de su implementación .

Otro enfoque que encontré es establecer un delegado para el navigationController:willShowViewController:animated: NavigationController y establecer el valor de NavigationBarHidden en el navigationController:willShowViewController:animated:

 - (void)navigationController:(UINavigationController *)navController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{ // hide the nav bar if going home if (viewController == homeViewController) [navController setNavigationBarHidden:YES animated:animated]; else [navController setNavigationBarHidden:NO animated:animated];} 

Manera fácil de personalizar el comportamiento para cada ViewController todo en un solo lugar.

Puse el código en el delegado viewWillAppear en cada vista que se muestra:

Me gusta esto donde necesitas esconderlo:

 - (void)viewWillAppear:(BOOL)animated { [yourObject hideBar]; } 

Me gusta donde debes mostrarlo:

 - (void)viewWillAppear:(BOOL)animated { [yourObject showBar]; } 

Un ligero cambio que tuve que hacer en las otras respuestas es solo mostrar la barra en vista. Desaparecerá si la razón por la que desaparece se debe a que se presiona un elemento de navigation. Esto se debe a que la vista puede desaparecer por otros motivos.

Así que solo muestro la barra si esta vista ya no es la vista más alta:

 - (void) viewWillDisappear:(BOOL)animated { if (self.navigationController.topViewController != self) { [self.navigationController setNavigationBarHidden:NO animated:animated]; } [super viewWillDisappear:animated]; } 

en Swift 3:

 override func viewWillAppear(_ animated: Bool) { navigationController?.navigationBar.isHidden = true super.viewWillAppear(animated) } override func viewWillDisappear(_ animated: Bool) { if (navigationController?.topViewController != self) { navigationController?.navigationBar.isHidden = false } super.viewWillDisappear(animated) } 

La respuesta actualmente aceptada no coincide con el comportamiento previsto descrito en la pregunta. La pregunta pide que la barra de navigation se oculte en el controller de vista raíz, pero visible en cualquier otro lado, pero la respuesta aceptada esconde la barra de navigation en un controller de vista particular. ¿Qué sucede cuando otra instancia del primer controller de vista se introduce en la stack? Ocultará la barra de navigation aunque no estamos mirando el controller de vista raíz.

En cambio, la estrategia de @Chad M. de usar UINavigationControllerDelegate es buena, y aquí hay una solución más completa. Pasos:

  1. Subclass UINavigationController
  2. Implementar el -navigationController:willShowViewController:animated método -navigationController:willShowViewController:animated para mostrar u ocultar la barra de navigation en function de si muestra el controller de vista raíz
  3. Reemplace los methods de initialization para configurar la subclass UINavigationController como su propio delegado

El código completo de esta solución se puede encontrar en este artículo . Aquí está el navigationController:willShowViewController:animated implementación navigationController:willShowViewController:animated :

 - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { /* Hide navigation bar if root controller */ if ([viewController isEqual:[self.viewControllers firstObject]]) { [self setNavigationBarHidden:YES animated:animated]; } else { [self setNavigationBarHidden:NO animated:animated]; } } 

Después de varios juicios aquí es cómo lo hice funcionar para lo que quería. Esto es lo que estaba intentando. – Tengo una vista con una image. y quería tener la image en pantalla completa. – También tengo un controller de navigation con tabBar. Entonces necesito esconder eso también. – Además, mi requisito principal no era solo esconderme, sino también tener un efecto de desvanecimiento mientras se mostraba y se escondía.

Así es como lo hice funcionar.

Paso 1: Tengo una image y el usuario hace clic en esa image una vez. Captura ese gesto y lo imageViewController en el nuevo imageViewController , está en imageViewController , quiero tener una image de pantalla completa.

 - (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer { NSLog(@"Single tap"); ImageViewController *imageViewController = [[ImageViewController alloc] initWithNibName:@"ImageViewController" bundle:nil]; godImageViewController.imgName = // pass the image. godImageViewController.hidesBottomBarWhenPushed=YES;// This is important to note. [self.navigationController pushViewController:godImageViewController animated:YES]; // If I remove the line below, then I get this error. [CALayer retain]: message sent to deallocated instance . // [godImageViewController release]; } 

Paso 2: todos estos pasos a continuación están en ImageViewController

Paso 2.1 – En ViewDidLoad, muestre el navBar

 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. NSLog(@"viewDidLoad"); [[self navigationController] setNavigationBarHidden:NO animated:YES]; } 

Paso 2.2: en viewDidAppear , configure una tarea de timer con retraso (la tengo configurada durante 1 segundo). Y después del retraso, agrega efecto de desvanecimiento. Estoy usando alfa para usar desvanecimiento.

 - (void)viewDidAppear:(BOOL)animated { NSLog(@"viewDidAppear"); myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(fadeScreen) userInfo:nil repeats:NO]; } - (void)fadeScreen { [UIView beginAnimations:nil context:nil]; // begins animation block [UIView setAnimationDuration:1.95]; // sets animation duration self.navigationController.navigationBar.alpha = 0.0; // Fades the alpha channel of this view to "0.0" over the animationDuration of "0.75" seconds [UIView commitAnimations]; // commits the animation block. This Block is done. } 

Paso 2.3: en viewWillAppear , agregue un gesto de OneTap a la image y haga que el navBar sea translúcido.

 - (void) viewWillAppear:(BOOL)animated { NSLog(@"viewWillAppear"); NSString *path = [[NSBundle mainBundle] pathForResource:self.imgName ofType:@"png"]; UIImage *theImage = [UIImage imageWithContentsOfFile:path]; self.imgView.image = theImage; // add tap gestures UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; [self.imgView addGestureRecognizer:singleTap]; [singleTap release]; // to make the image go full screen self.navigationController.navigationBar.translucent=YES; } - (void)handleTap:(UIGestureRecognizer *)gestureRecognizer { NSLog(@"Handle Single tap"); [self finishedFading]; // fade again. You can choose to skip this can add a bool, if you want to fade again when user taps again. myTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(fadeScreen) userInfo:nil repeats:NO]; } 

Paso 3 – Finalmente, en vista viewWillDisappear , asegúrese de volver a colocar todas las cosas.

 - (void)viewWillDisappear: (BOOL)animated { self.hidesBottomBarWhenPushed = NO; self.navigationController.navigationBar.translucent=NO; if (self.navigationController.topViewController != self) { [self.navigationController setNavigationBarHidden:NO animated:animated]; } [super viewWillDisappear:animated]; } 

En caso de que alguien que todavía tenga problemas con el backswipe canceló un error ya que @fabb comentó en la respuesta aceptada.

Me las arregla para solucionar esto anulando viewDidLayoutSubviews , además de viewWillAppear/viewWillDisappear como se muestra a continuación:

 override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) self.navigationController?.setNavigationBarHidden(false, animated: animated) } override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) self.navigationController?.setNavigationBarHidden(true, animated: animated) } //*** This is requinetworking to fix navigation bar forever disappear on fast backswipe bug. override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() self.navigationController?.setNavigationBarHidden(false, animated: false) } 

En mi caso, me doy count de que se debe a que el controller de vista raíz (donde se oculta la navigation) y el controller de vista comprimido (nav se muestra) tienen diferentes styles de barra de estado (p. Ej., Oscuro y claro). En el momento en que inicie el backswipe para abrir el controller de vista, habrá animation de color de barra de estado adicional. Si suelta su dedo para cancelar el pop interactivo, mientras que la animation de la barra de estado no está terminada , ¡la barra de navigation se habrá ido para siempre!

Sin embargo, este error no ocurre si los styles de barra de estado de ambos controlleres de vista son iguales.

Si lo que desea es ocultar la barra de navigation completamente en el controller, una solución mucho más limpia es, en el controller de raíz, tener algo como:

 @implementation MainViewController - (void)viewDidLoad { self.navigationController.navigationBarHidden=YES; //...extra code on view load } 

Cuando presiona una vista secundaria en el controller, la barra de navigation permanecerá oculta; si desea mostrarlo solo en el elemento secundario, agregará el código para mostrarlo it(self.navigationController.navigationBarHidden=NO;) en la viewWillAppear llamada viewWillAppear y, de forma similar, el código para ocultarlo en la vista viewWillDisappear

La implementación más simple puede ser simplemente hacer que cada controller de vista especifique si su barra de navigation está oculta o no en su viewWillAppear:animated: method. El mismo enfoque también funciona bien para ocultar / mostrar la barra de herramientas también:

 - (void)viewWillAppear:(BOOL)animated { [self.navigationController setToolbarHidden:YES/NO animated:animated]; [super viewWillAppear:animated]; } 

Al implementar este código en su ViewController puede get este efecto. En realidad, el truco es ocultar la barra de navigation cuando se lanza ese controller

 - (void)viewWillAppear:(BOOL)animated { [self.navigationController setNavigationBarHidden:YES animated:YES]; [super viewWillAppear:animated]; } 

y mostrar la barra de navigation cuando el usuario abandona esa página, hacer esto es viewWillDisappear

 - (void)viewWillDisappear:(BOOL)animated { [self.navigationController setNavigationBarHidden:NO animated:YES]; [super viewWillDisappear:animated]; } 

Respuesta compatible Simple Swift 3: use un segue y preséntelo de manera modal. Está en línea con la documentation de Apple. https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/NavigationControllers.html

Ejemplo: Controlador de página de inicio de session -> Controlador de navigation -> Crear nuevo controller de count (con el button Atrás que se vincula a la página de inicio de session a través de segue que se presenta de manera modal)

Al volver a vincular a otra página en la que no desea que aparezca la barra de navigation, cree una segue a esa página, en el ejemplo, adjúntela al button Atrás y arrástrela a la página de inicio de session, pero select Presente Modalmente. Todo esto se puede hacer desde Main.storyboard.

¡No se necesita encoding!

La ocultación de la barra de navigation solo en la primera página también se puede lograr a través de storyboard. En el guión gráfico, goto Escena del controller de navigation-> Barra de navigation . Y select la propiedad ' Oculto ' del inspector de Atributos . Esto ocultará la barra de navigation desde el primer controller de vista hasta que sea visible para el controller de vista requerido.

La barra de navigation se puede configurar de nuevo a visible en la callback ViewWillAppear de ViewController.

 -(void)viewWillAppear:(BOOL)animated { [self.navigationController setNavigationBarHidden:YES animated:animated]; [super viewWillAppear:animated]; }