如何通过导航控制器传递委托?

Posted

技术标签:

【中文标题】如何通过导航控制器传递委托?【英文标题】:How to pass delegate thru Navtigation Controller? 【发布时间】:2021-12-28 06:59:33 【问题描述】:

我有 2 个 VC,它们之间有一个导航控制器。如何将 First screen 设置为 Second 的代表?

我尝试了什么:

    从第一个开始展示 SecondVC(它在没有导航的情况下展示它) 在 NavVC viewDidLoad() 中设置委托

第一VC:

    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()
    

导航控制器:

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

第二个VC:

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

【问题讨论】:

【参考方案1】:

这里的主要任务是从导航控制器实例(navC)访问第二个视图控制器实例。要实现这一点,您必须首先从导航控制器实例(nextVC)访问 rootViewController,如下所示:

    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)

当第二个视图控制器是导航控制器的根时,上面的代码适用。如果第二个视图控制器不是 navC 的根控制器,那么您必须迭代控制器以获取第二个视图控制器实例。一旦有第二个控制器实例,您就可以将委托分配给如下所示。

    for controller in navC.viewControllers 
        if controller.isKind(of: SecondVC.self) 
           if let secondVc = controller as? SecondVC 
              secondVc.delegate = self
           
           break
        
    

【讨论】:

【参考方案2】:

我处理了同样的事情。在 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()
    

在第二个视图控制器上,调用 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
        
    
    

【讨论】:

以上是关于如何通过导航控制器传递委托?的主要内容,如果未能解决你的问题,请参考以下文章

跨子导航控制器传递数据

Swift - 通过导航控制器委托

使用委托将数据传回导航堆栈

如何从 App 委托导航内部视图控制器

通过视图控制器将委托传递给视图控制器

在 prepareForSeque 时委托不是 nil,但在导航表视图中调用时为 nil