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;
}
Foi útil?

Solução

A solução mais legal que eu tenho encontrado é fazer o seguinte na primeira vista controller .

Objectivo-C

- (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:

  1. subclasse UINavigationController
  2. 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
  3. 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

- (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:

  1. 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)
        }
    }

}
  1. classe Set do seu UINavigationController em storyboard para MyNavigationController MyNavigationController É isso aí!

Diferença entre resposta e os meus de Chad-m:

  1. Herdar do UINavigationController, então você não vai poluir o seu RootViewController.

  2. uso self.viewControllers.first em vez de homeViewController, 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];
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top