Swift:通过storyboardID实例化将数据传递给NavigationController的第一个子实例

时间:2018-11-06 10:01:29

标签: swift

我想将数据传递给嵌入在viewController中的第一个navigationController

要访问此导航控制器,它有一个storyBoardID,我到达了实例化navigationController,但无法传递数据,

这是我的代码:

extension UINavigationController {

func dismissAndPresentNavigationController(from storyboard: UIStoryboard?, identifier: String) {
    guard let navigationController = storyboard?.instantiateViewController(withIdentifier: identifier) as? UINavigationController else { return }

    print("OK")
    if let nav = navigationController.navigationController?.viewControllers.first as? ChatBotViewController{
        print("OK2")
    }

    self.dismiss(animated: false, completion: nil)
    self.present(navigationController, animated: true, completion: nil)
}

}

我在参数中输入的标识符是导航控制器的storyBoardID

如何将数据传输到navigationcontroller的第一个控制器?

解决方案:

extension UINavigationController {

func dismissAndPresentNavigationController(from storyboard: UIStoryboard?, identifier: String, with fittoBottle: FittoBottle) {
    guard let navigationController = storyboard?.instantiateViewController(withIdentifier: identifier) as? UINavigationController else { return }

    if let nav = navigationController.viewControllers.first as? ChatBotViewController{
        nav.fittoBottle = fittoBottle
    }

    self.dismiss(animated: false, completion: nil)
    self.present(navigationController, animated: true, completion: nil)
}

2 个答案:

答案 0 :(得分:1)

从情节提要中实例化导航控制器后,您将能够通过navigationController.viewControllers.first访问根视图控制器。

guard let navigationController = storyboard?.instantiateViewController(withIdentifier: identifier) as? UINavigationController else { return }

if let chatBotViewController = navigationController.viewControllers.first as? ChatBotViewController {
    chatBotViewController.fittoBottle = fittoBottle
}

self.dismiss(animated: false, completion: nil)
self.present(navigationController, animated: true, completion: nil)

答案 1 :(得分:0)

要在iOS应用中的视图控制器之间进行通信,最好的方法是使用protocol(代理)或Notification。对于您而言,扩展UINavigationController听起来不是一个好主意,因为您不应该将扩展方法传递给实例视图控制器,然后再将任何数据传递给它,作为扩展方法,UINavigationController并不负责请注意ChatBotViewController或任何其他实例化控制器。

根据我的建议,在故事板上要显示ChatBotViewController的任何地方,为ChatBotViewController(嵌入在UINavigationController中)创建一个演示模态序列,然后使用performSegue(withIdentifier:sender:)来启动导航控制器,并覆盖prepare(for:sender:)来设置要在ChatBotViewController中传递的数据。

以下是一些解释代码:

import UIKit

struct FittoBottle {

}

class ChatBotViewController: UIViewController {

  var fittoBottle = FittoBottle()

}

class ViewController: UIViewController {

  func showChatController() {

    /*
     If there is any controller is presented by this view controller
     or one of its ancestors in the view controller hierarchy,
     we will dismiss it first.
     */
    if presentedViewController != nil {

      dismiss(animated: true) {
        self.showChatController()
      }
      return

    }

    // Data that will be sent to the new controller
    let fittoBottle = FittoBottle()

    // ChatBotViewControllerSegue is the segue identifier set in your storyboard.
    performSegue(withIdentifier: "ChatBotViewControllerSegue", sender: fittoBottle)


  }

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    guard let navigationController = segue.destination as? UINavigationController else {
      return
    }

    guard let chatBotController = navigationController.viewControllers.first as? ChatBotViewController else {
      return
    }

    // Get the data from sender, if not found, create it there.
    // Or if you don't pass it through sender, you can specify it here.
    let fittoBottle = sender as? FittoBottle ?? FittoBottle()
    chatBotController.fittoBottle = fittoBottle


  }

}