swiftpushviewcontrolleruicontainerviewpresentviewcontroller

using pushViewController in containerView Not work


I have created containerView which contain tableViewController. The main issue, when user click on information, tableViewController must show the information which user clicked.

it show the information when I use present(<#T##UIViewController#>, animated: <#T##Bool#>, completion: <#T##(() -> Void)?#>) but doesnt work if I call self.navigationController?.pushViewController

the main issue is when I make vc.info = info it doesnt work, the info has value but using injection the value in another class is nil.

Here is my code:

func showLoginDetailsOnIpad(encryptedDataBase: info) {

    self.view.addSubview(loginContainer)
    let mainStoryboard : UIStoryboard?
    mainStoryboard = UIStoryboard(name: "StoryboardiPad", bundle: nil)

    let vc = mainStoryboard!.instantiateViewController(withIdentifier: "tableVC") as! tableVC
    vc.info = info
    vc.showingLoginInfo = true
    vc.modalPresentationStyle = .automatic

    self.navigationController?.pushViewController(vc, animated: true)

}

Solution

  • Explanation

    You mentioned the use of a containerView. The table controller being displayed inside the containerView, doesn't automatically get a reference to the nearest navigationController.

    So in this line: self.navigationController?.pushViewController(vc, animated: true)

    self.navigationController might actually be nil. You can confirm this by printing its value before running the push method like so:

    print(self.navigationController) // See if this prints nil.
    self.navigationController?.pushViewController(vc, animated: true)
    

    Fixes

    To fix the issue, I suggest to pass a reference to the parent controller's navigationController to the child controller - through the embed segue.

    In your parent controller, you can use this code:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destination = segue.destination as? UITableViewController{
            destination.navigationController = self.navigationController
        }
    }
    

    And in your table view controller, leave the code as is.