iPhone esconder barra de navegação apenas na primeira página
-
21-08-2019 - |
Pergunta
Eu tenho o código abaixo que esconde e mostra a barra de navegação. Ele está escondido quando as primeiras cargas Exibir e depois escondido quando os "filhos" obter chamado. O problema é que não consigo encontrar o evento / ação para provocá-lo para esconder novamente quando voltar para a exibição de raiz ....
Eu tenho um botão "teste" na página raiz que faz manualmente a ação, mas não é bonito e eu quero que seja automático.
-(void)hideBar
{
self.navController.navigationBarHidden = YES;
}
-(void)showBar
{
self.navController.navigationBarHidden = NO;
}
Solução
A solução mais legal que eu tenho encontrado é fazer o seguinte na primeira vista controller .
- (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];
}
Swift
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)
}
Isto fará com que a barra de navegação para animar na esquerda (junto com a próxima exibição) quando você empurra a próxima UIViewController
na pilha, e animar o para a esquerda (em conjunto com a antiga visão), quando você pressiona o botão de volta no UINavigationBar
.
Por favor, note também que estes não são delegar métodos, você está substituindo a implementação de UIViewController
desses métodos, e de acordo com a documentação que você deve chamar algum lugar implementação do Super em sua implementação .
Outras dicas
Outra abordagem que eu encontrei é para definir um delegado para o NavigationController
:
navigationController.delegate = self;
e uso setNavigationBarHidden
em navigationController:willShowViewController:animated:
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
// Hide the nav bar if going home.
BOOL hide = viewController != homeViewController;
[navigationController setNavigationBarHidden:hide animated:animated];
}
Fácil maneira de personalizar o comportamento de cada ViewController
tudo em um só lugar.
Um ligeiro ajuste eu tive que fazer nas outras respostas é apenas unhide o bar em viewWillDisappear se a razão que está a desaparecer é devido a um item de navegação sendo empurrado sobre ele. Isso ocorre porque a vista pode desaparecer por outras razões.
Então eu só unhide bar se essa visão não é mais o ponto de vista superior:
- (void) viewWillDisappear:(BOOL)animated
{
if (self.navigationController.topViewController != self)
{
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
[super viewWillDisappear:animated];
}
Gostaria de colocar o código no viewWillAppear que está sendo mostrado delegado em cada vista:
como este onde você precisa escondê-lo:
- (void)viewWillAppear:(BOOL)animated
{
[yourObject hideBar];
}
como este onde você precisa mostrar que:
- (void)viewWillAppear:(BOOL)animated
{
[yourObject showBar];
}
em 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)
}
A resposta aceito atualmente não corresponde ao comportamento pretendido descrito na pergunta. A questão pede a barra de navegação para ser escondida no controlador de vista raiz, mas visível em toda a parte, mas as peles resposta aceita a barra de navegação em um controlador de vista particular. O que acontece quando outra instância do primeiro controlador de vista é empurrado para a pilha? Ele irá esconder a barra de navegação, mesmo que não estão olhando para o controlador de vista raiz.
Em vez disso, estratégia href="https://stackoverflow.com/a/6418606/2434476"> UINavigationControllerDelegate é uma boa, e aqui é um mais solução completa. Etapas:
- subclasse
UINavigationController
- Implementar o método
-navigationController:willShowViewController:animated
para mostrar ou ocultar a barra de navegação com base em se ele está mostrando a exibição de raiz controlador - Substitua os métodos de inicialização para definir a subclasse UINavigationController como seu próprio delegado
código completo para esta solução pode ser encontrada no este Gist. Aqui está a implementação 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];
}
}
Depois de vários ensaios aqui está como eu tenho que trabalhar para o que eu queria. Isto é o que eu estava tentando. - Eu tenho uma visão com uma imagem. e eu queria ter a imagem ir tela cheia. - Eu tenho um controlador de navegação com uma barra de páginas também. Então eu preciso esconder isso também. - Além disso, a minha principal requisito não estava apenas se escondendo, mas ter um efeito de esmaecimento também enquanto mostrando e escondendo
.Isto é como eu tenho que trabalhar.
Passo 1 - Eu tenho uma imagem de usuário e torneiras em que a imagem uma vez. I capturar esse gesto e empurrá-lo para a nova imageViewController
, a sua no imageViewController
, eu quero ter imagem em tela cheia.
- (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];
}
Passo 2 - Todos esses passos abaixo estão no ImageViewController
Passo 2.1 - Em ViewDidLoad, mostrar barra de navegação
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(@"viewDidLoad");
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}
Passo 2.2 - Em viewDidAppear
, configurar uma tarefa temporizador com atraso (eu tenho isso definido para 1 atraso sec). E após o atraso, adicionar efeitos de desbotamento. Eu estou usando alfa para uso desaparecendo.
- (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.
}
passo 2.3 - Sob viewWillAppear
, adicione gesto SingleTap à imagem e fazer o translúcido navBar.
- (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];
}
Passo 3 - Finalmente, em viewWillDisappear
, certifique-se de colocar todas as coisas de volta ??p>
- (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];
}
dar o meu crédito para @ Chade-m 's resposta.
Aqui é a versão Swift:
- Criar um novo
MyNavigationController.swift
arquivo
import UIKit
class MyNavigationController: UINavigationController, UINavigationControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.delegate = self
}
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if viewController == self.viewControllers.first {
self.setNavigationBarHidden(true, animated: animated)
} else {
self.setNavigationBarHidden(false, animated: animated)
}
}
}
Diferença entre resposta e os meus de Chad-m:
-
Herdar do UINavigationController, então você não vai poluir o seu RootViewController.
-
uso
self.viewControllers.first
em vez dehomeViewController
, para que você não vai fazer isso 100 vezes para seus 100 UINavigationControllers em 1 StoryBoard.
Em caso de alguém ainda tendo problemas com o backswipe rápido bug cancelada como @fabb comentado na resposta aceita.
eu conseguir resolver isso, substituindo viewDidLayoutSubviews
, além de viewWillAppear/viewWillDisappear
como mostrado abaixo:
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 required to fix navigation bar forever disappear on fast backswipe bug.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.navigationController?.setNavigationBarHidden(false, animated: false)
}
No meu caso, eu noto que é porque o controlador de vista raiz (onde nav está escondido) eo controlador de vista empurrado (nav é mostrado) tem diferentes estilos da barra de status (por exemplo, claro e escuro ). O momento que você começar a backswipe estalar o controlador de vista, haverá animação adicional cor da barra de status. Se você soltar o dedo, a fim de cancelar o pop interativa, enquanto a animação da barra de status não está terminado , a barra de navegação está perdido para sempre!
No entanto, este erro não ocorre se estilos da barra de status de ambos os controladores de vista são os mesmos.
Se o que você quer é esconder a barra de navegação completamente no controlador, uma solução mais limpa tanto é, no controlador de raiz, tem algo como:
@implementation MainViewController
- (void)viewDidLoad {
self.navigationController.navigationBarHidden=YES;
//...extra code on view load
}
Quando você empurra uma visão da criança no controlador, a barra de navegação permanecerão ocultas; se você quiser exibi-lo apenas na criança, você vai adicionar o código para exibir it(self.navigationController.navigationBarHidden=NO;)
no callback viewWillAppear
, e da mesma forma o código para esconder-lo em viewWillDisappear
A implementação mais simples pode ser apenas para ter cada controlador de vista especificar se a sua barra de navegação está escondido ou não em seu método viewWillAppear:animated:
. A mesma abordagem funciona bem para esconder / mostrar a barra de ferramentas, bem como:
- (void)viewWillAppear:(BOOL)animated {
[self.navigationController setToolbarHidden:YES/NO animated:animated];
[super viewWillAppear:animated];
}
navegação Hiding bar apenas na primeira página pode ser alcançado através de storyboard bem. No storyboard, Goto Controlador de navegação da cena> Barra de Navegação . E selecione ' Oculto ' propriedade do inspetor Atributos . Esta barra de navegação irá esconder a partir de primeiro viewcontroller até sua visível para o viewcontroller necessário.
barra de navegação pode ser definido de volta para visíveis em viewWillAppear callback de ViewController.
-(void)viewWillAppear:(BOOL)animated {
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
}
Swift 4:
No controlador de vista que você deseja ocultar a barra de navegação do.
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)
}
Ao implementar este código em seu ViewController você pode obter este efeito Na verdade, o truque é, esconder o NavigationBar quando esse controlador é iniciada
- (void)viewWillAppear:(BOOL)animated {
[self.navigationController setNavigationBarHidden:YES animated:YES];
[super viewWillAppear:animated];
}
e exibir a barra de navegação quando a licença de usuário que a página fazer isso é viewWillDisappear
- (void)viewWillDisappear:(BOOL)animated {
[self.navigationController setNavigationBarHidden:NO animated:YES];
[super viewWillDisappear:animated];
}