UINavigationContoller interactivePopGestureRecognizer inactive when navigation bar is hidden

13,003

Solution 1

Set your UIViewController subclass as the gestureRecognizer's delegate:

self.navigationController.interactivePopGestureRecognizer.delegate = self;

That's it!

Solution 2

Simple solution

Just set the hidden property of the navigation bar not through navigation controller

Just use these two lines

self.navigationController.navigationBarHidden = NO;
self.navigationController.navigationBar.hidden = YES;

Solution 3

I used this. self.navigationController.interactivePopGestureRecognizer.delegate = self;

also in my UINavigationController class to disable interactivePopGestureRecognizer during transitions.

- (void)pushViewController:(UIViewController *)viewController
              animated:(BOOL)animated
{
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.interactivePopGestureRecognizer.enabled = NO;
}

    [super pushViewController:viewController animated:animated];
}

- (void)navigationController:(UINavigationController *)navigationController
       didShowViewController:(UIViewController *)viewController
                    animated:(BOOL)animated
{
    if ([navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        // disable interactivePopGestureRecognizer in the rootViewController of navigationController
        if ([[navigationController.viewControllers firstObject] isEqual:viewController]) {
            navigationController.interactivePopGestureRecognizer.enabled = NO;
        } else {
            // enable interactivePopGestureRecognizer
            navigationController.interactivePopGestureRecognizer.enabled = YES;
        }
    }
}

the reason of disable interactivePopGestureRecognizer in rootViewController is:when swipe from edge in rootViewController and then tap something to push in next viewController, the UI won't accept any touches now.Press home button to put app in background , and then tap it to enter foreground...

Solution 4

This doesn't seem to work for me. I followed Keithl's blog post. Neither did that work.

I ultimately settled with UISwipeGestureRecognizer. It seems to do what it says.

UISwipeGestureRecognizer *gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(backButtonPressed:)];
[gestureRecognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.navigationController.view addGestureRecognizer:gestureRecognizer];
Share:
13,003

Related videos on Youtube

Dan
Author by

Dan

Updated on June 04, 2022

Comments

  • Dan
    Dan almost 2 years

    I have a view controller which is nested within a UINavigationController.

    I have implemented the iOS 7 interactivePopGestureRecognizer to enable the user to gesture to pop a VC off the stack.

    Within the VC i have a scrollview and whilst the user is not at the top of the scrollview I hide all the chrome (Navigation bar and status bar) to place focus on the content.

    However with the navigation bar hidden, the interactivePopGestureRecognizer is not working.

    I have tried enabling it after it has disappeared and verified it is not nil, however it still doesn't work.

    Is there anything I am missing?

  • Dan
    Dan over 10 years
    Thanks, in fact setting it to nil also works. I wonder if this is a bug?
  • Mr. Míng
    Mr. Míng over 10 years
    There will be a bug if set self.navigationController.interactivePopGestureRecognizer.de‌​legate to self or nil: Swipe from the edge of the screen, and tap something to push a view controller into the navigation controller quickly, then -- 1. The current view controller does not respond any touch event; 2. The new view contrller will not be shown; 3. Swipe from the edge of the screen again, the new view contrller will be shown; 4. Call popViewControllerAnimated: with the animated parameter set to NO (tap the custom back button), crash!
  • Dennis
    Dennis about 10 years
    It looks like just setting the delegate isn't enough, see the crash report by @iwill. The workaround we found was to store the original delegate, e.g. in viewDidLoad, set yourself as the new one in viewDidAppear: and then reset it again to the original one in viewDidDisappear:. Kinda strange, but works.
  • ninjaneer
    ninjaneer about 10 years
    @Dennis having the same problem, but I tried your solution, doesn't seem to be working.
  • Arie Litovsky
    Arie Litovsky about 10 years
    I would not recommend this solution. It resulted in several bugs when presenting/popping view controllers.
  • Alexi Akl
    Alexi Akl almost 9 years
    You should set it in viewDidAppear -(void)viewDidAppear:(BOOL)animated { self.navigationController.interactivePopGestureRecognizer.de‌​legate = self; }
  • malex
    malex over 8 years
    If you want to use further interactivePop in your navigation stack you have to save delegate object before changing interactivePopGestureRecognizer.delegate and restore the initial value when UIViewController disappears.
  • nekonari
    nekonari about 7 years
    Did you mean to use UIEdgePanGestureRecognizer?
  • Tiago Lopes
    Tiago Lopes over 6 years
    Not an ideal solution but it'll do in a pinch.
  • user7097242
    user7097242 about 6 years
    @iwill did you ever figure out how to do this right? Im experiencing the same exact issue you mentioned/
  • user7097242
    user7097242 about 6 years
    @ArieLitovsky what would you suggest for this then?
  • Mr. Míng
    Mr. Míng about 6 years
    @user7097242 I posted an answer stackoverflow.com/a/20672693/456536