iosswiftxcodenavigationpushviewcontroller

swift navigation controller return nil when trying to navigate to another View Controller


We have Router class to navigate the viewController to another view controller, It's working as expected but when randomly the viewControllersStack gets nil and crash occurred. We tried to use it "if let" to avoid the crash but the issue here is black screen appeared when the viewControllersStack is nil. so we have reverted it back. Can you suggest why the navigation stack is nil if the navigation is nil how to handle it?

private func PopOrPushToViewController(_ strControllerClass: String) {

    //get the list of controllers in the stack
    let viewControllersStack: [UIViewController] = self.navigationController!.viewControllers as [UIViewController]
    var boolDidNaviagtion = false
    for viewController in viewControllersStack {
        if boolDidNaviagtion {
            viewController.removeFromParent()
        }
        if String(describing: type(of: viewController)) == strControllerClass {
            boolDidNaviagtion = true
            self.navigationController?.popToViewController(viewController, animated: true)
        }
    }
    if !boolDidNaviagtion {
        let viewController = NavigationController.sharedInstance.storyboardViewControllerFromString(strControllerClass)!
        self.navigationController!.pushViewController(viewController, animated: true)
    }
}



class AddTripViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func navigate(_ sender: Any) {
        popOrPushToViewController( "ListViewController")
    }

}

Solution

  • The problem is likely your use of:

    viewController.removeFromParent()
    

    If you pop to a VC in the stack, the other VCs will be removed automatically.

    Try changing your func to this:

    private func PopOrPushToViewController(_ strControllerClass: String) {
    
        // get the list of controllers in the stack
        if let vcStack: [UIViewController] = self.navigationController?.viewControllers {
    
            var didPop = false
    
            for vc in vcStack {
    
                // if we find the desired VC already in the navVC's stack of controllers,
                // pop to it, set the didPop flag to true, and quit looking
                if String(describing: type(of: vc)) == strControllerClass {
                    self.navigationController?.popToViewController(vc, animated: true)
                    didPop = true
                    break
                }
    
            }
    
            // if we did NOT pop to the desired VC,
            // instantiate it and push it onto the stack
            if !didPop {
                if let vc = NavigationController.sharedInstance.storyboardViewControllerFromString(strControllerClass) {
                    navigationController?.pushViewController(vc, animated: true)
                }
            }
    
        }
    
    }