Back Button Callback in Navigationcontroller in iOS

Execute action when back bar button of UINavigationController is pressed

One option would be implementing your own custom back button. You would need to add the following code to your viewDidLoad method:

- (void) viewDidLoad {
[super viewDidLoad];
self.navigationItem.hidesBackButton = YES;
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleBordered target:self action:@selector(back:)];
self.navigationItem.leftBarButtonItem = newBackButton;
}

- (void) back:(UIBarButtonItem *)sender {
// Perform your custom actions
// ...
// Go back to the previous ViewController
[self.navigationController popViewControllerAnimated:YES];
}

UPDATE:

Here is the version for Swift:

    override func viewDidLoad {
super.viewDidLoad()
self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Bordered, target: self, action: "back:")
self.navigationItem.leftBarButtonItem = newBackButton
}

func back(sender: UIBarButtonItem) {
// Perform your custom actions
// ...
// Go back to the previous ViewController
self.navigationController?.popViewControllerAnimated(true)
}

UPDATE 2:

Here is the version for Swift 3:

    override func viewDidLoad {
super.viewDidLoad()
self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.plain, target: self, action: #selector(YourViewController.back(sender:)))
self.navigationItem.leftBarButtonItem = newBackButton
}

func back(sender: UIBarButtonItem) {
// Perform your custom actions
// ...
// Go back to the previous ViewController
_ = navigationController?.popViewController(animated: true)
}

back button callback in navigationController in iOS

William Jockusch's answer solve this problem with easy trick.

-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// back button was pressed. We know this is true because self is no longer
// in the navigation stack.
}
[super viewWillDisappear:animated];
}

How to detect back button is pressed in the next viewController in a navigationController

I'm suggesting you to do that with Notification Center like AglaiaZ suggested you. But if you're not feeling comfortable with using Notification Center, then try this more basic solution with viewWillAppear delegate method in viewController from which you're tracking are you back from B VC. So, let's go.

Set this variable in your current view controller class where you want to trigger method when the back button is pressed on the specific view controller, let's call that specific view controller B VC.

let isFromBViewController = false

Then in code block where you're triggering the transition to B VC set this variable to true.

func goToBViewController() { // This method is triggering transition from A VC to B VC
isFromBViewController = true }

And then in viewWillAppear delegate method check did current VC from which we triggered the transition to B VC have appeard from B VC.

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

if isFromBViewController {
// code for doing something when you got back from B VC

isFromBViewController = false
}}

And that's it.

But, again I'm suggesting you to use the notification center as @AglaiaZ suggested, the tutorial is easy, and with that tutorial I've also learned how to use Notification Center and how to create and use custom notifications.

Good luck.

UINavigationController and back button action

Or you can use the UINavigationController's delegate methods. The method willShowViewController is called when the back button of your VC is pressed.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;

Intercepting ios back button to send back to base view controller

  1. As @the4kman mentioned , we can create a custom button to replace the LeftBarButtonItem ,and handle the back event .

ViewDidLoad in B

this.NavigationItem.LeftBarButtonItem = 
new UIBarButtonItem("back", UIBarButtonItemStyle.Plain, (sender,e) => {
UIViewController baseVC = NavigationController.ViewControllers[NavigationController.ViewControllers.Length - 3];
NavigationController.PopToViewController(baseVC, true);
});

  1. As @J.C. Chaparro mentioned , remove A from stack .

ViewDidLoad in B

List<UIViewController> list = NavigationController.ViewControllers.ToList<UIViewController>();
list.RemoveAt(list.Count-2);
NavigationController.ViewControllers = list.ToArray();

Go back to root when nav back button is press

Personally I would not recommend what you are trying to achieve, but anyways here is a different solution without customizing the back button.

Steps to implement

  1. Create CustomNavigationController by subclassing
    UINavigationController
  2. Override popViewController(animated:)
  3. When ViewController conforms to Navigationable and

    • shouldCustomNavigationControllerPopToRoot() returns true, call super.popToRootViewController
    • Otherwise proceed with normally popping the ViewController

Source Code

Custom Navigation Controller

import UIKit

class CustomNavigationController: UINavigationController {

// MARK: - Initializers

override init(rootViewController: UIViewController) {
super.init(rootViewController: rootViewController)

initialSetup()
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)

initialSetup()
}

// MARK: - Setups

private func initialSetup() {
// DISCLAIMER: This code does not support `interactivePopGestureRecognizer`, therefore we disable it
interactivePopGestureRecognizer?.delegate = nil
}

// MARK: - Overrides

override func popViewController(animated: Bool) -> UIViewController? {
if shouldNavigationPopToRoot {
return super.popToRootViewController(animated: animated)?.last
}

return super.popViewController(animated: animated)
}

// MARK: - Helpers

private var shouldNavigationPopToRoot: Bool {
return (topViewController as? Navigationable)?.shouldCustomNavigationControllerPopToRoot() == true
}
}

View Controller conforming to Navigationable

import UIKit

protocol Navigationable: class {
func shouldCustomNavigationControllerPopToRoot() -> Bool
}

class ViewController: UIViewController, Navigationable {

// MARK: - Protocol Conformance
// MARK: Navigationable

func shouldCustomNavigationControllerPopToRoot() -> Bool {
return true
}
}

Output

CustomNavigationController

Programmatically create navigation controller with back button

Here is simple example for you which can set navigation bar Programmatically from first View:

if let resultController = storyboard!.instantiateViewControllerWithIdentifier("SecondView") as? SecondView {
let navController = UINavigationController(rootViewController: resultController) // Creating a navigation controller with resultController at the root of the navigation stack.
self.presentViewController(navController, animated:true, completion: nil)
}

If you wan to add back button into that navigation then use this code into SecondView.swift class:

override func viewDidLoad() {
super.viewDidLoad()

let backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "goBack")
navigationItem.leftBarButtonItem = backButton

}

func goBack(){
dismissViewControllerAnimated(true, completion: nil)
}

If you want to do all of this from firstView then here is your code:

@IBAction func btnPressed(sender: AnyObject) {

if let resultController = storyboard!.instantiateViewControllerWithIdentifier("SecondView") as? SecondView {
resultController.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "goBack")
let navController = UINavigationController(rootViewController: resultController) // Creating a navigation controller with VC1 at the root of the navigation stack.
self.presentViewController(navController, animated:true, completion: nil)
}
}

func goBack(){
dismissViewControllerAnimated(true, completion: nil)
}

Hope this will help you.



Related Topics



Leave a reply



Submit