Search code examples
iosswiftuiviewcontrollerxcode6uinavigationbar

Change destination of Navigation Back button


How can I change the view controller the default navigation back button takes me to? The back button usually takes you back to the previous view controller. But what if I want it to go back by two view controllers? I mean I want to change the view controller the back button takes me to. I do not prefer creating a custom back button. So is there any other way? Probably an unwind segue linked to the back button or something?


Solution

  • Probably easiest way to achieve behaviour you want is to use navigationController.setViewControllers(controllers, animated: true).

    If you want to go 2 controllers back from controller A instead of only one, use this custom segue when presenting A:

    class ReplaceControllerSegue: UIStoryboardSegue {
        override func perform() {
            if let navigationController = sourceViewController.navigationController as UINavigationController? {
                var controllers = navigationController.viewControllers
                controllers.removeLast()
                controllers.append(destinationViewController)
                navigationController.setViewControllers(controllers, animated: true)
            }
        }
    }
    

    Here is nice tutorial how to set custom class for your segue in Interface Builder: http://blog.jimjh.com/a-short-tutorial-on-custom-storyboard-segues.html

    If you are presenting controller via code, use this category:

    extension UINavigationController {
        func replaceCurrentViewControllerWith(viewController: UIViewController, animated: Bool) {
            var controllers = viewControllers
            controllers.removeLast()
            controllers.append(viewController)
            setViewControllers(controllers, animated: animated)
        }
    }
    

    Then just use self.navigationController!.replaceCurrentViewControllerWith(newController, animated: true) instead of self.navigationControllerPushViewController(newController, animated: true).

    It's easy to adjust this code to remove as much controllers as you need.