KUROYUKI
KUROYUKI

Reputation: 123

Go back to root when nav back button is press

I have the method to check when the back button in navigation bar is press and the method go back to root page but for some reason when self.navigationController?.popToRootViewController(animated: true) it only go back to the previous page. do anyone know how to go back to the root when navigation bar back button is pressed?

override func didMove(toParentViewController parent: UIViewController?) {
    super.didMove(toParentViewController: parent)

    if parent == nil{
        self.navigationController?.popToRootViewController(animated: true)

    }

}

In this question he is asking how to what method can he use to customise his back button. In my code its able to detect when user press on back button and self.navigationController?.popToRootViewController(animated: true) is suppose to bring the page back to the root page, however there are somethings in the system preventing my app to go back to the root page.

Upvotes: 0

Views: 1530

Answers (2)

E-Riddie
E-Riddie

Reputation: 14780

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

Upvotes: 0

Arie Pinto
Arie Pinto

Reputation: 1292

i think the best way is to create your own custom back button at this page

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

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

credit to this answer by 'fr33g' : Execute action when back bar button of UINavigationController is pressed

Upvotes: 5

Related Questions