Ascendant
Ascendant

Reputation: 2579

How to hide Navigation Bar without losing slide-back ability

I have a UITableView and it has a nav bar(got from UINavigationViewController), it's able to go back by sliding back using a finger.

I tried to hide the nav bar but keep the slide-back ability, code:

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

This successfully hid the nav bar, however, I can no longer slide back to the last screen either.

Is there any way to hide the nav bar but keep the slide-back ability?

Upvotes: 31

Views: 16619

Answers (9)

Starsky
Starsky

Reputation: 2048

Here is a working code for Swift 5:

private func setupNavController() {
            
    navigationController?.setNavigationBarHidden(true, animated: true)     
    self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
    if let interactivePopGestureRecognizer = navigationController?.interactivePopGestureRecognizer {
        self.tableView.panGestureRecognizer.require(toFail: interactivePopGestureRecognizer)
    }
}

I have a UIViewController which contains a UITableView inside. This code helps you keep the smooth transition when you swipe back or press the back button. Call this function in viewWillAppear.

Upvotes: 1

Sean Stayns
Sean Stayns

Reputation: 4244

Zinan Xings solution in Swift 4.2 (Please give him upvote!):

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    self.navigationController?.setNavigationBarHidden(true, animated: true)
    self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
    self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}

Upvotes: 2

atereshkov
atereshkov

Reputation: 4565

Swift 4.x and iOS 11.4.

The @gabbler solution is still working. Idk, looks like this is a UIKit bug, but..

Just use:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    self.navigationController?.navigationBar.isHidden = true
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    self.navigationController?.navigationBar.isHidden = false
}

Upvotes: 3

Abdullah Tahan
Abdullah Tahan

Reputation: 2129

for Xamarin Forms i was Struggle with this so first don't NavigationRenderer you'll get NavigationController null instead use PageRenderer:

[assembly: Xamarin.Forms.ExportRenderer(typeof(ContentPage), typeof(ContentPageRenderer))]
namespace sample
{
    class ContentPageRenderer : PageRenderer
    {
        public override void ViewWillAppear(bool animated)
        {
            base.ViewDidAppear(animated);

            var navctrl = this.ViewController.NavigationController;
            navctrl.InteractivePopGestureRecognizer.Delegate = new UIGestureRecognizerDelegate();
            navctrl.InteractivePopGestureRecognizer.Enabled = true;

        }
    }
}

Upvotes: 1

Ber.to
Ber.to

Reputation: 1104

Tested with Swift 2 the solution of @gabbler, if you use

self.navigationController?.navigationBar.hidden = true

Swift 3.0

self.navigationController?.navigationBar.isHidden = true

instead of

self.navigationController?.navigationBarHidden = true

the swipe back gesture works like a charm!

Upvotes: 66

Ascendant
Ascendant

Reputation: 2579

Found the solution:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // hide nav bar
    [[self navigationController] setNavigationBarHidden:YES animated:YES];

    // enable slide-back
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        self.navigationController.interactivePopGestureRecognizer.delegate = self;
    }
}


- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return YES;
}

And in .h file, conform to UIGestureRecognizerDelegate

Upvotes: 25

Prabhu.Somasundaram
Prabhu.Somasundaram

Reputation: 1390

If hiding the the navigation bar did't help, try changing the rect of the navigation bar and see?

navBarBgFrame.origin.y = - navBarBgFrame.size.height;

Upvotes: 0

Wyetro
Wyetro

Reputation: 8588

Make sure to include:

self.navigationController.navigationBar.hidden = YES;

And:

self.navigationController.interactivePopGestureRecognizer.delegate = self;

And:

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
    }

It should appear like this:

- (void)viewWillAppear:(BOOL)animated {

    self.navigationController.navigationBar.hidden = YES;
    self.navigationController.interactivePopGestureRecognizer.delegate = self;
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
            self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        }
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return YES;
}

Upvotes: 3

gabbler
gabbler

Reputation: 13766

Use

self.navigationController.navigationBar.hidden = YES;

or add this line in viewWillAppear:

self.navigationController.interactivePopGestureRecognizer.delegate = self;

It seems the interaction is not effective, adding this line and make the view controller conforms to the UIGestureRecognizerDelegate protocol will make it work.

Upvotes: 7

Related Questions