skip to Main Content

I have 2 VC’s, and one navigation controller between them. How can i set First screen as a delegate of Second?

What i tried:

  1. Present SecondVC from frist (it presents it without navigation)
  2. Setting delegate in NavVC viewDidLoad()

FirstVC:

    class MainVC: UIViewController, SecondVCDelegate {
    func passData(text: String) {
        // do stuff
    }
    @IBAction func openNextVC(_ sender: Any) {
        let nextVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "NavVC") as! NavVC
        present(nextVC, animated: true, completion: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

Navigation Controller:

class NavVC: UINavigationController {  
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

SecondVC:

    protocol SecondVCDelegate {
    func passData(text: String)
    }
    
    class SecondVC: UIViewController {
        var delegate: SecondVCDelegate?
    
        @IBAction func save(_ sender: Any) {
           // do stuff
        }
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    }

2

Answers


  1. Main task here would be to access second view controller instance from navigation controller instance(navC). And to achieve this, you have to first access the rootViewController from your navigation controller instance(nextVC) as below:

        let nextVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "NavVC") as! NavVC
        let secondVC = nextVC?.viewControllers.first as? SecondVC
        secondVC.delegate = self 
        present(nextVC, animated: true, completion: nil)
    

    The above code is applicable when second view controller is the root of your navigation controller. If second view controller is not the root controller to navC, then you have to iterate the controllers to get second view controller instance. Once second controller instance is there, then you can assign the delegate to the same as below.

        for controller in navC.viewControllers {
            if controller.isKind(of: SecondVC.self) {
               if let secondVc = controller as? SecondVC {
                  secondVc.delegate = self
               }
               break
            }
        }
    
    Login or Signup to reply.
  2. I handled the same thing. Try this on MainVC:

     class MainVC: UIViewController, SecondVCDelegate {
        func passData(text: String) {
            // do stuff
        }
        @IBAction func openNextVC(_ sender: Any) {
            guard let secondController = self.storyboard?.instantiateViewController(withIdentifier: "AddGroupVC") as? AddGroupVC else { return }
            secondController.delegate = { [weak self] in
                  print("call your delegates here")
                        
              }
          self.navigationController?.present(secondController, animated: true, completion: nil)
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    }
    

    On second View Controller, call the delegates in viewWillDisappear :

    class SecondVC: UIViewController {
            var delegate: SecondVCDelegate?
        
            @IBAction func save(_ sender: Any) {
               // do stuff
          self.dismiss(animated: true, completion: nil)
            }
            override func viewDidLoad() {
                super.viewDidLoad()
            }
     override func viewWillDisappear(_ animated: Bool) {
            
            self.delegate  
        }
     }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search