iPhone hides navigation bar on first page only

Keywords: Swift

I have the following code to hide and show the navigation bar. It is hidden when the first view is loaded and then when "children" is called. The trouble is, when they go back to the root view, I can't find the event / action that triggered it to hide again

I have a "test" button on the root page for manual execution, but it's not beautiful, and I hope it's automatic.

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

#1 building

The best solution I've found is to do the following in the first view controller.

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

rapid

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

When you press the next UIViewController on the stack, this causes the navigation bar to animate from the left (with the next view) and move to the left (with the old view) when you press the back button.

Note that these are not delegate methods, you want to override UIViewController's implementation of these methods, and according to the documentation, you must call super's implementation somewhere in the implementation.

#2 building

The currently accepted answer does not match the expected behavior described in the question. This question requires the navigation bar to be hidden on the root view controller, but visible anywhere else, but the accepted answer hides the navigation bar on the specific view controller. What happens when another instance of the first view controller is pushed onto the stack? Even if we don't see the root view controller, it hides the navigation bar.

Instead, @ Chad M. uses the strategy It's a good one strategy , which is a more complete solution. Pace:

  1. Subclass UINavigationController
  2. Implement the - navigationController:willShowViewController:animated method to show or hide the navigation bar based on whether it shows the root view controller or not
  3. Override the initialization method to set the UINavigationController subclass to its own delegate

The complete code for this solution can be found in In this Gist Find it. This is the navigationController:willShowViewController:animated implementation:

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

#3 building

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

#4 building

If @ fabb comments in the accepted answer, anyone still encounters a quick backlash problem and cancels the error.

In addition to viewwillappearance / viewwilldisappear, I try to solve this problem by overriding viewDidLayoutSubviews as follows:

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

In my example, I noticed that this is because the root view controller (navigation is hidden) and the rolled out view controller (display navigation) have different status bar styles (for example, dark and bright). The moment you start reverse scanning to pop up the view controller, there will be other status bar color animations. If you release your fingers to cancel the interactive pop-up, the navigation bar will disappear forever before the status bar animation is complete!

However, this error does not occur if both view controllers have the same status bar style.

#5 building

By implementing this code in the ViewController, you can achieve this effect by actually hiding the navigationBar when the Controller starts

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

Unhide the navigation bar when the user leaves the page this is viewWillDisappear

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

Posted by help_lucky on Tue, 18 Feb 2020 21:01:06 -0800