Question

J'ai le code ci-dessous qui cache et affiche la barre de navigation. Il est masqué lors du chargement de la première vue, puis masqué lorsque les & "Enfants &"; se faire appeler. Le problème, c’est que je ne trouve pas l’événement / l’action à déclencher pour le masquer à nouveau quand ils reviennent à la vue racine ....

J'ai un " test " bouton sur la page racine qui fait manuellement l'action mais ce n'est pas joli et je veux que ce soit automatique.

-(void)hideBar 
{
    self.navController.navigationBarHidden = YES;
}
-(void)showBar 
{       
    self.navController.navigationBarHidden = NO;
}
Était-ce utile?

La solution

La solution la plus agréable que j'ai trouvée consiste à effectuer les opérations suivantes dans le premier contrôleur de vue .

Objective-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)
} 

La barre de navigation s'animera à partir de la gauche (avec la vue suivante) lorsque vous appuierez le UIViewController suivant sur la pile, puis s'éloignera à gauche (avec l'ancienne vue), lorsque vous appuyez sur le bouton de retour sur le UINavigationBar.

Notez également que ce ne sont pas des méthodes de délégation, vous redéfinissez la mise en oeuvre de <=> ces méthodes et, selon la documentation, vous devez appeler cette implémentation quelque part dans votre implémentation .

Autres conseils

Une autre approche que j'ai trouvée consiste à définir un délégué pour le NavigationController:

navigationController.delegate = self;

et utilisez setNavigationBarHidden dans 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];
}

Moyen facile de personnaliser le comportement de chaque ViewController en un seul endroit.

Un léger ajustement que j'ai dû faire sur les autres réponses consiste à afficher uniquement la barre dans viewWillDisappear si la raison de sa disparition est due à un élément de navigation inséré dessus. En effet, la vue peut disparaître pour d'autres raisons.

Je n’affiche donc la barre que si cette vue n’est plus la vue la plus haute:

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

    [super viewWillDisappear:animated];
}

Je placerais le code dans le délégué viewWillAppear à chaque vue affichée:

Comme ceci, vous devez le cacher:

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

Comme ceci, vous devez le montrer:

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

dans 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 réponse actuellement acceptée ne correspond pas au comportement prévu décrit dans la question. La question demande à ce que la barre de navigation soit masquée sur le contrôleur de vue racine, mais visible partout ailleurs, mais la réponse acceptée masque la barre de navigation sur un contrôleur de vue particulier. Que se passe-t-il lorsqu'une autre instance du premier contrôleur de vue est placée dans la pile? Cela masquera la barre de navigation même si nous ne cherchons pas le contrôleur de vue racine.

Au lieu de cela, la stratégie de @Chad M. d'utilisation du UINavigationControllerDelegate est un bon choix. une solution plus complète. Étapes:

  1. sous-classe UINavigationController
  2. Implémentez la méthode -navigationController:willShowViewController:animated pour afficher ou masquer la barre de navigation en fonction de l'affichage du contrôleur de vue racine
  3. Redéfinissez les méthodes d'initialisation pour définir la sous-classe UINavigationController en tant que son propre délégué

Le code complet de cette solution est disponible dans ce Gist . Voici la navigationController:willShowViewController:animated mise en œuvre:

- (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];
    }
}

Après plusieurs essais, voici comment j’ai obtenu les résultats escomptés. C'est ce que j'essayais. - J'ai une vue avec une image. et je voulais que l'image passe en plein écran. - J'ai aussi un contrôleur de navigation avec une barre de tabulation. Donc, je dois cacher ça aussi. - De plus, mon exigence principale ne consistait pas uniquement à me cacher, mais aussi à atténuer son effet lors de l'affichage et du masquage.

C'est comme ça que je l'ai fait fonctionner.

Étape 1 - J'ai une image et l'utilisateur tape sur cette image une fois. Je capture ce geste et le pousse dans le nouveau imageViewController, il se trouve dans le viewDidAppear, je souhaite obtenir une image en plein écran.

- (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];
} 

Étape 2 - Toutes ces étapes ci-dessous sont dans ImageViewController

Étape 2.1 - Dans ViewDidLoad, affichez la barre de navigation

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

Étape 2.2 - Dans viewWillAppear, configurez une tâche de minuterie avec un délai (je l’ai configurée pour un délai de 1 seconde). Et après le délai, ajoutez un effet de fondu. J'utilise l'alpha pour utiliser la décoloration.

- (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.
}

étape 2.3 - Sous viewWillDisappear, ajoutez un geste singleTap à l'image et rendez le navBar translucide.

- (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];
 }

Étape 3 - Enfin, dans <=>, assurez-vous de remettre tout ce que vous avez

.
- (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];
}

Donnez mon crédit à la réponse de @ chad-m.

Voici la version Swift:

  1. Créer un nouveau fichier MyNavigationController.swift
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. Définissez la classe de votre UINavigationController dans StoryBoard sur MyNavigationController MyNavigationController C'est tout!

Différence entre la réponse de chad-m et la mienne:

  1. Héritez de UINavigationController pour ne pas polluer votre rootViewController.

  2. utilisez self.viewControllers.first plutôt que homeViewController, vous ne le ferez donc pas 100 fois pour vos 100 contrôleurs UINavigation dans 1 StoryBoard.

Au cas où quelqu'un aurait toujours des problèmes avec le bogue annulé d'analyse rapide , comme @fabb l'a commenté dans la réponse acceptée.

Je parviens à résoudre ce problème en remplaçant viewDidLayoutSubviews, en plus de viewWillAppear/viewWillDisappear comme indiqué ci-dessous:

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

Dans mon cas, je remarque que c'est parce que le contrôleur de vue racine (où la navigation est masquée) et le contrôleur de vue avancée (la navigation est affichée) a différents styles de barre d'état (par exemple, sombre et clair). ). Au moment où vous lancez le balayage arrière pour faire apparaître le contrôleur de vue, l'animation des couleurs de la barre d'état se poursuit. Si vous relâchez le doigt pour annuler la pop interactive, tant que l'animation de la barre d'état n'est pas terminée , la barre de navigation est définitivement partie!

Toutefois, ce bogue ne survient pas si les styles de barre d'état des deux contrôleurs de vue sont identiques.

Si vous souhaitez masquer complètement la barre de navigation dans le contrôleur, une solution beaucoup plus propre consiste à utiliser, dans le contrôleur racine, quelque chose comme:

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

Lorsque vous poussez une vue enfant dans le contrôleur, la barre de navigation reste masquée. si vous souhaitez l'afficher uniquement dans l'enfant, vous allez ajouter le code permettant d'afficher it(self.navigationController.navigationBarHidden=NO;) dans le viewWillAppear rappel, et de la même manière le code permettant de le masquer viewWillDisappear

La mise en oeuvre la plus simple peut consister à demander à chaque contrôleur de vue de spécifier si sa barre de navigation est masquée ou non dans sa méthode viewWillAppear:animated:. La même approche fonctionne bien pour afficher / masquer la barre d’outils:

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

Vous pouvez également masquer la barre de navigation sur la première page uniquement via le storyboard. Dans le scénario, accédez à Scène du contrôleur de navigation - & Gt; Barre de navigation . Sélectionnez ensuite la propriété Cachée dans l'inspecteur Attributs . Cela masquera la barre de navigation à partir du premier contrôleur de vue jusqu'à ce qu'elle soit visible pour le contrôleur de vue requis.

La barre de navigation peut être redéfinie sur visible dans le rappel ViewWillAppear de ViewController.

-(void)viewWillAppear:(BOOL)animated {

    [self.navigationController setNavigationBarHidden:YES animated:animated];
    [super viewWillAppear:animated];                                                  
}

Swift 4:

Dans le contrôleur de vue, vous souhaitez masquer la barre de navigation.

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

En implémentant ce code dans votre ViewController, vous pouvez obtenir cet effet.  En réalité, l'astuce consiste à masquer la barre de navigation lorsque ce contrôleur est lancé

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

et affichez la barre de navigation lorsque l'utilisateur quitte cette page. viewWillDisappear

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:NO animated:YES];
    [super viewWillDisappear:animated];
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top