Override back button in navigation stack while keeping appearance of default back button?

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];
}

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 ;)


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