Reputation: 19600
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
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
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
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
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
Reputation: 86
try adding this into the custom back button self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
Upvotes: 0
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
Reputation: 8247
What did you do in "navigateBack" ?
Use this method like this :
- (void)navigateBack
{
[self.navigationController popViewControllerAnimated:YES];
}
Upvotes: 0