使用导航控制器在“prepareForSegue”中设置数据

Posted

技术标签:

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

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

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

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

【问题讨论】:

【参考方案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】:

    在 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 !"
            
        
    
    

    将标识符 segue 编辑为“showNavigationController”

    在您的 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,请执行以下操作...

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

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

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

    (可选)如果您需要将数据与 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)

    在您用于启动 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

【讨论】:

以上是关于使用导航控制器在“prepareForSegue”中设置数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 prepareForSegue 方法从视图控制器推送到导航视图控制器?

将选项卡栏控制器嵌入导航控制器时的 prepareForSegue

使用 prepareForSegue 设置方法值

prepareForSegue 在 iOS 7 上无法获取目标视图控制器

为啥我的 prepareForSegue 崩溃

使用 prepareForSegue 在视图控制器之间传递数据