I'm trying to overwrite the default action of the back button in a navigation controller. I've provided a target an action on the custom button. The odd thing is when assigning it though the backbutton attribute it doesn't pay attention to them and it just pops the current view and goes back to the root:
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle: @"Servers"
style:UIBarButtonItemStylePlain
target:self
action:@selector(home)];
self.navigationItem.backBarButtonItem = backButton;
As soon as I set it through the leftBarButtonItem
on the navigationItem
it calls my action, however then the button looks like a plain round one instead of the arrowed back one:
self.navigationItem.leftBarButtonItem = backButton;
How can I get it to call my custom action before going back to the root view? Is there a way to overwrite the default back action, or is there a method that is always called when leaving a view (viewDidUnload
doesn't do that)?
It isn't possible to do directly. There are a couple alternatives:
UIBarButtonItem
that validates on tap and pops if the test passesUITextField
delegate method, such as-textFieldShouldReturn:
, which is called after theReturn
orDone
button is pressed on the keyboardThe downside of the first option is that the left-pointing-arrow style of the back button cannot be accessed from a custom bar button. So you have to use an image or go with a regular style button.
The second option is nice because you get the text field back in the delegate method, so you can target your validation logic to the specific text field sent to the delegate call-back method.
The solution I have found so far is not very nice, but it works for me. Taking this answer, I also check whether I'm popping programmatically or not:
You have to add that property to your controller and set it to YES before popping programmatically:
I don't believe this is possible, easily. The only way I believe to get around this is to make your own back button arrow image to place up there. It was frustrating for me at first but I see why, for consistency's sake, it was left out.
You can get close (without the arrow) by creating a regular button and hiding the default back button:
Here is Swift 3 version of @oneway's answer for catching navigation bar back button event before it gets fired. As
UINavigationBarDelegate
cannot be used forUIViewController
, you need to create a delegate that will be triggered whennavigationBar
shouldPop
is called.And then, in your view controller add the delegate function:
I've realised that we often want to add an alert controller for users to decide whether they wanna go back. If so, you can always
return false
innavigationShouldPopOnBackButton()
function and close your view controller by doing something like this:Found new way to do it :
Objective-C
Swift
I've implemented UIViewController-BackButtonHandler extension. It does not need to subclass anything, just put it into your project and override
navigationShouldPopOnBackButton
method inUIViewController
class:Download sample app.