【问题标题】:Set data in `prepareForSegue` with navigation controller使用导航控制器在“prepareForSegue”中设置数据
【发布时间】:2015-05-01 13:02:09
【问题描述】:

我正在用 Swift 开发一个 iOS 应用程序。

我想使用prepareForSegue 函数将数据从一个视图发送到另一个视图。

但是,我的目标视图前面有一个导航控制器,所以它不起作用。如何在导航控制器中包含的 VC 上设置数据?

【问题讨论】:

    标签: ios swift uinavigationcontroller


    【解决方案1】:

    prepareForSegue 中访问目标导航控制器,然后访问它的顶部:

    let destinationNavigationController = segue.destination as! UINavigationController
    let targetController = destinationNavigationController.topViewController
    

    您可以从目标控制器访问其视图并传递数据。

    在旧版本 - 现在已过时 - Swift 和 UIKit 版本中,代码略有不同:

    let destinationNavigationController = segue.destinationViewController as UINavigationController
    let targetController = destinationNavigationController.topViewController
    

    【讨论】:

    • 使用了这段代码,但使用 targetController 点了一些东西,我无法在 secondViewController 中访问我的 var receivedTest
    • @biggreentree 您很可能需要将destinationNavigationController.topViewController 转换为secondViewController 的类型。
    【解决方案2】:
    1. 在 SendViewController 中准备转场

      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
          if segue.identifier == "segueShowNavigation" {
              if let destVC = segue.destination as? UINavigationController,
                  let targetController = destVC.topViewController as? ReceiveViewController {
                  targetController.data = "hello from ReceiveVC !"
              }
          }
      }
      
    2. 将标识符 segue 编辑为“showNavigationController”

    1. 在您的 ReceiveViewController 中添加

    这个

    var data : String = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("data from ReceiveViewController is \(data)")
    }
    

    当然您可以发送任何其他类型的数据(int、Bool、JSON ...)

    【讨论】:

      【解决方案3】:

      使用optional binding 和 Swift 3 & 4 完成答案:

      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
          if let navigationVC = segue.destination as? UINavigationController, let myViewController = navigationVC.topViewController as? MyViewControllerClass {
              myViewController.yourProperty = myProperty
          }
      }
      

      【讨论】:

        【解决方案4】:

        这是 Swift 3 的答案:

        let svc = segue.destination as? UINavigationController
        
        let controller: MyController = svc?.topViewController as! MyController
        controller.myProperty = "Hi there"
        

        【讨论】:

          【解决方案5】:

          Swift 3 中的单行:

          override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let vc = segue.destination.childViewControllers[0] as? FooController {
              vc.variable = localvariable
            }
          }
          

          【讨论】:

            【解决方案6】:

            在 Swift 5 中

            如果您不仅必须从 SourceViewController 转到嵌入在 UINavigationController 中的 DestinationViewController,而且还必须转到新的 Storyboard,请执行以下操作...

            1. 在 Interface Builder 中的源 ViewController 旁边放置一个来自 Object Library 的“Storyboard Reference”对象,然后将一个 segue 拖到它上面(例如,从 SourceViewController 视图上的一个按钮)。例如,将 segue 标识符命名为“ToOtherStoryboard”。

            2. 转到 NavigationViewController 并使用 Identity Inspector 为其指定 Storyboard ID。 “DestinationNavVC”可以。

            3. 单击您在步骤 1 中创建的 Storyboard Reference 图标,并在其属性检查器的“引用 ID”字段中,输入您在步骤 2 中为 UINavigationController 编写的 Storyboard ID。这将创建从源到 DestinationViewController 的转场不管你在源 ViewController 的源文件中写了什么。这是因为连接到 NaviationController 会自动显示 UINavigationController 的根 ViewController(第一个)。

            4. (可选)如果您需要将数据与 segue 一起附加并将其发送到 DestinationViewController 中的属性,您可以在 SourceViewController 文件的 Prepare-For-Segue 方法中编写以下代码:

              override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                  if segue.identifier == "ToOtherStoryboard" {
                      let destinationNavVC = segue.destination as! UINavigationController
                      let destinationVC = destinationNavVC.topController as!     DestinationViewController
              
                      destinationVC.name = nameTextField.text // for example
                      destinationVC.occupation = occupationTextField.text
                  }
              }
              

              如果您只是想从一个 ViewController 移动到另一个 ViewController,则不需要 PrepareForSegue,上述方法将起作用(无需步骤 3)

            5. 在您用于启动 segue 的按钮的 IBAction Outlet 方法中,您可以编写:

              performSegue(withIdentifer: "ToOtherStoryboard", sender: self)
              

            【讨论】:

            • 代码编辑器(控制K)不适用于以“覆盖”开头的代码部分,也许bc其中一行代码很长?。
            【解决方案7】:

            在 segue 箭头属性中设置标识符名称,以便在 performeSegue 中使用。

            像这样:

            override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            
                if let vc: ProfileViewController = segue.destination as? ProfileViewController {
            
                    //do any setting to the next screen
            
                }
            
            }
            

            然后:

                performSegue(withIdentifier: "yourIdentifierOfViewProfile", sender: indexPath.row)
            

            希望对你有帮助。

            【讨论】:

              【解决方案8】:

              最好跳过对UINavigationController 的检查,因为可能有多个segues 使用navigationController,因此将对每个使用navigationControllersegue 进行检查。更好的方法是检查children 的第一个viewController 并将其转换为您要查找的viewController

              if let destVC = segue.destination.children.first as? MyViewController {
                  destVC.hideBottomBar = true
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-03-09
                • 2014-02-17
                • 2012-10-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-12-01
                相关资源
                最近更新 更多