UINavigationBar: intercept back button and back swipe gesture
Asked Answered
A

1

5

I have a UINavigationBar that intercepts the back button tap that alerts the user if there are unsave changes. This is based on the solution presented in UINavigationController and UINavigationBarDelegate.ShouldPopItem() with MonoTouch using the UINavigationBarDelegate protocol and implementing - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;

Now, iOS7 has introduced the swipe-to-go-back gesture, and I'd like to intercept that as well, but can't get it to work with the solutions I've found so far, namely using [self.interactivePopGestureRecognizer addTarget:self action:@selector(handlePopGesture:)]; and

- (void)handlePopGesture:(UIGestureRecognizer *)gesture {
    if (gesture.state == UIGestureRecognizerStateEnded) {
        [self popViewControllerAnimated:NO];
    }
}

While this does pop the views, it leaves the navigation bar buttons in place, so I'm ending up with a back button that leads nowhere, as well as all other navigation button I've added to the nav bar. Any tips?

Alejandroalejo answered 19/4, 2014 at 15:29 Comment(0)
V
11

To intercept the back swipe gesture you can set self as the delegate of the gesture (<UIGestureRecognizerDelegate>) and then return YES or NO from gestureRecognizerShouldBegin based on unsaved changes:

// in viewDidLoad
self.navigationController.interactivePopGestureRecognizer.delegate = self;

// ...
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if ([gestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {

        if (self.dirty) {
            // ... alert
            return NO;
        } else
            return YES;
    } else 
        return YES;
}

In the alert you can ask to the user if she want to go back anyway and, in that case, pop the controller in alertView clickedButtonAtIndex:

Hope this is of some help.

Vicenta answered 19/4, 2014 at 17:13 Comment(1)
I expected to see some problems if I changed the delegate of the gesture recognizer from its default, but I haven't seen any yet. The default delegate is an object of the class _UINavigationInteractiveTransition. I changed it to my custom subclass of UINavigationController, and it seems to be working fine.Scurrility

© 2022 - 2024 — McMap. All rights reserved.