How do I override the back button for just one view (not for all the back buttons present in different views) such that on click of the back button, the root view controller is shown?
-
You can't do exactly what you want. You have to do something like what the other two answers provide. If you want to retain all characteristics of back, but override what happens sometimes, prefer nacho4d's answer. Otherwise, prefer Mike Bretz's answer. – Jason Coco Feb 23 '11 at 00:32
-
you can refer to this http://stackoverflow.com/a/44019989/1556386 – Baig May 17 '17 at 08:54
10 Answers
You need to replace the backbutton and associate an action handler:
- (void)viewDidLoad {
[super viewDidLoad];
// change the back button to cancel and add an event handler
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@”back”
style:UIBarButtonItemStyleBordered
target:self
action:@selector(handleBack:)];
self.navigationItem.leftBarButtonItem = backButton;
}
- (void)handleBack:(id)sender {
// pop to root view controller
[self.navigationController popToRootViewControllerAnimated:YES];
}

- 10,879
- 7
- 50
- 81

- 1,956
- 18
- 19
-
7Hi, Thanks for the answer, but I wanted to retain the back button style and over ride the back button implementation rather than creating an new button. – Pintu Feb 23 '11 at 00:07
-
7Apple Guidelines do not "allow" changing expected behaviours of UI elements, e.g. of back buttons. When an iOS user sees the "normal" back button style, she expects normal back button behaviour. If you like to change this behaviour, you should implement a "normal" styled button. – Mike Bretz Feb 23 '11 at 00:46
-
Hi, kind of an old answer, but I have a question: The button created wont look like a normal back button right(like an arrow to the left)? Also, altering it will only alter the curent view controller right? The other VCs will have normal back buttons right? Thank you very much. – pedros Nov 08 '12 at 23:33
-
@MikeBretz Maybe just an out of date comment, but for future readers. In some cases you want to overwrite the behavior because you want to provide a different transition into the previousViewController - in that case I see no problem overwriting this behavior. It still is doing what the user expects, it's just taking a different code path. – 1dayitwillmake Dec 07 '12 at 21:02
-
4as for me, if the user push back, and hasnt saved whats on the current screen, i want to show a popup saying "are you sure you want to go back without saving?" im sure that would be acceptable – Fonix Jan 24 '13 at 07:24
-
Why would you release the back button memory while the view is still loaded? – Timothy Swan Aug 10 '14 at 21:38
-
Instead of `self.navigationItem.leftBarButtonItem`, you should use `self.navigationItem.backBarButtonItem` for better handling. – atulkhatri May 09 '16 at 11:26
-
-
Thank you! your answer helped me. a side note though or a warning i got when using `UIBarButtonItemStyleBordered`: `UIBarButtonItemStyleBordered` is deprecated: first deprecated in iOS 8.0 - Use UIBarButtonItemStylePlain when minimum deployment target is iOS7 or later – Sam Jan 24 '19 at 14:00
Found a solution which retains the back button style as well. Add the following method to your view controller.
-(void) overrideBack{
UIButton *transparentButton = [[UIButton alloc] init];
[transparentButton setFrame:CGRectMake(0,0, 50, 40)];
[transparentButton setBackgroundColor:[UIColor clearColor]];
[transparentButton addTarget:self action:@selector(backAction:) forControlEvents:UIControlEventTouchUpInside];
[self.navigationController.navigationBar addSubview:transparentButton];
}
Now provide a functionality as needed in the following method:
-(void)backAction:(UIBarButtonItem *)sender {
//Your functionality
}
All it does is to cover the back button with a transparent button ;)

- 3,819
- 4
- 23
- 36
-
You should remove the transparentButton from superView when leaving the view controller because if not it will continue added to the navigation Bar in other viewControllers – Chuy47 May 04 '16 at 21:39
-
8
-
1
-
Well for a start if you are going to do this you could at least make sure the frame of the transparent button is correct in `-viewWillLayoutSubviews` otherwise your back button may have a large title and this button won't cover it. A better solution is to completely replace the back button with a custom view with an image and label to replicate the style. There are countless other better solutions, this one is inherently hacky. – simonthumper Oct 28 '16 at 14:08
-
It's old, but the correct answer is that:
Instead of pushing your ViewController on top of all the others, you'd better replace the full stack with the rootVC and the new VC only.
Not:
self.navigationController?.pushViewController(myVc, animated: true)
But:
let vcStack = self.navigationController?.viewControllers
self.navigationController?.setViewControllers([vcStack![0],myVc], animated: true)
Like that, on back it will just popToRoot because it's the previous viewController in stack

- 829
- 7
- 13
I had the similar problem and I successfully used the answer given by Sarasranglt. Here is the SWIFT version.
override func viewDidLoad() {
let transparentButton = UIButton()
transparentButton.frame = CGRectMake(0, 0, 50, 40)
transparentButton.backgroundColor = UIColor.orangeColor()
transparentButton.addTarget(self, action:"backAction:", forControlEvents:.TouchUpInside)
self.navigationController?.navigationBar.addSubview(transparentButton)
}
And the function is
func backAction(sender:UIButton) {
// Some sction
}

- 773
- 10
- 6
Another approach is to adopt UINavigationControllerDelegate Protocol.
– navigationController:willShowViewController:animated:
– navigationController:didShowViewController:animated:
Those methods will let you know when a controller appears but you have to check that controller is the controller you want.

- 43,720
- 45
- 157
- 240
-
1HI, thanks for the answer, but is there any way where in I can override the back method implementation. – Pintu Feb 23 '11 at 00:12
-
2
For keeping same appearance you can use :
UIView *leftButtonView = [[UIView alloc]initWithFrame:CGRectMake(-12, 0, 105, 30)];
UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
leftButton.frame = leftButtonView.frame;
[leftButton setImage:[UIImage imageNamed:@"ic_system_back"] forState:UIControlStateNormal];
[leftButton setTitle:@"title" forState:UIControlStateNormal];
[leftButton.titleLabel setLineBreakMode:NSLineBreakByTruncatingTail];
[leftButton.titleLabel setFont:[UIFont systemFontOfSize:16]];
[leftButton setTitleEdgeInsets: UIEdgeInsetsMake(0, 8, 0, 0)];
[leftButton addTarget:self action:@selector(handleBack:) forControlEvents:UIControlEventTouchUpInside];
[leftButtonView addSubview:leftButton];
UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc]initWithCustomView:leftButtonView];
self.navigationItem.leftBarButtonItem = leftBarButton;
Following Sarasranglt's method of having a transparent button, in objective C, and Pavle Mijatovic's earlier swift version, here is a swift 4 version:
let transparentButton = UIButton()
transparentButton.frame = CGRect(x:0, y:0, width:50, height: 40)
transparentButton.backgroundColor = UIColor.clear
transparentButton.addTarget(self, action:#selector(backAction(sender:)), for:.touchUpInside)
self.navigationController?.navigationBar.addSubview(transparentButton)
and
@objc func backAction(sender:UIButton) {
// Some action
}

- 3,902
- 1
- 44
- 58
without making custom button or without any hack(transparentButton) just override 'viewWillDisappear' method and write your code inside the block.
override func viewWillDisappear(_ animated: Bool) {
// write your code...
}

- 791
- 1
- 7
- 27
The following code (written in C# for Xamarin iOS) will replace the back button with a custom one that looks just like the system implementation (chevron icon included).
The system "back" navigation will no longer fire, and you are free to handle the TouchUpInside as you wish.
Converting it to ObjC shouldn't take long, I'll leave that fun to you :)
var backButton = new UIButton(new CGRect(0, 0, 70.0, 70.0));
var symbolCfg = UIImageSymbolConfiguration.Create(UIFont.ButtonFontSize, UIImageSymbolWeight.Bold, UIImageSymbolScale.Large)
var backImage = UIImage.GetSystemImage("chevron.left", symbolCfg);
backButton.SetImage(backImage, forState: UIControlState.Normal);
backButton.TitleEdgeInsets = new UIEdgeInsets(10.0f, 10.0f, 10.0f, 0.0f);
backButton.SetTitle("Back", forState: UIControlState.Normal);
var backBarButton = new UIBarButtonItem(customView: backButton);
NavigationItem.LeftBarButtonItems = new[] { backBarButton };

- 4,159
- 4
- 32
- 53
Use this code to show a custom back button, Note the backBarButtonItem
before marking it as a duplicate answer.
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"< back"
style:UIBarButtonItemStylePlain
target:self
action:@selector(handleBack:)];
self.navigationItem.backBarButtonItem= backButton;
Cheers!

- 10,896
- 3
- 53
- 89