UINavigationBar: intercept back button and back sw

2019-04-10 18:33发布

问题:

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?

回答1:

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.