dlinsin
dlinsin

Reputation: 19600

iOS 7 Back Button Pop Gesture

In iOS 7 there's the new swipe to pop gesture: You swipe from left to right on the left side of your screen and the UINavigationController pops back to the previous UIViewController.

When I create a custom back button like this, the swipe to pop gestures doesn't work anymore:

UIBarButtonItem *customBackButton = [[UIBarButtonItem alloc] initWithTitle:@" " style:UIBarButtonItemStyleBordered target:self action:@selector(navigateBack)];
[customBackButton setBackButtonBackgroundImage:barBackBtnImg forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[customBackButton setBackButtonBackgroundImage:barBackBtnImgHighlighted forBarMetrics:UIBarMetricsDefault];
self.navigationItem.backBarButtonItem = customBackButton;

How can I use a custom back button and have the native swipe to pop gesture?

Update:

That's what's happening in navigateBack:

- (void)navigateBack {
    [self.navigationController popViewControllerAnimated:YES];
}

Upvotes: 16

Views: 29545

Answers (7)

Zeev Vax
Zeev Vax

Reputation: 924

To avoid crashes you have to be careful how you add and remove your custom back selector. The reason is that the navigation controller stays around while you pushing popping controller. As already stated after adding your custom back button+selector, you should do the following in viewDidApear.

    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
    {
       self.navigationController.interactivePopGestureRecognizer.enabled = YES;
       self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
       [self.navigationController.interactivePopGestureRecognizer addTarget:self action:@selector(navigateBack)];
    }

Then in viewWillDisapear do

        if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
        {
           [self.navigationController.interactivePopGestureRecognizer removeTarget:self action:@selector(performCompletion)];
        }

The timing of these calls is a key. You can run into crashes otherwise, see more details on the reason in here

Upvotes: 2

prizzl
prizzl

Reputation: 166

Just add the following line of code:

[self.navigationController.interactivePopGestureRecognizer addTarget:self action:@selector(handleGesture:)];

You can add your own UIGestureRecognizer and pop the UIViewController yourself. See the docs for further info.

Upvotes: 13

Albert Chu
Albert Chu

Reputation: 243

I use

[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"nav_back.png"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"nav_back.png"]];

[UIBarButtonItem.appearance setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -64) forBarMetrics:UIBarMetricsDefault];

Upvotes: 3

udit gupta
udit gupta

Reputation: 796

There is no need to add your own gesture recognizer. The UINavigationController already does that for you. You need to set the delegate for the interactivePopGestureRecognizer before enabling it.

Do the following two things:

self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
[self.navigationController.interactivePopGestureRecognizer setEnabled:YES];

Upvotes: 35

try adding this into the custom back button self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;

Upvotes: 0

YuliaSh.
YuliaSh.

Reputation: 795

There is a new gesture recognizer UIScreenEdgePanGestureRecognizer. You can add it to your view and handle respectively (call navigateBack), replicating view controllers navigation behaviour.

Upvotes: 1

Jordan Montel
Jordan Montel

Reputation: 8247

What did you do in "navigateBack" ?

Use this method like this :

- (void)navigateBack
{
    [self.navigationController popViewControllerAnimated:YES];
}

Upvotes: 0

Related Questions