使用导航控制器在“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 中访问我的 varreceivedTest
@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
,因此将对每个使用navigationController
的segue
进行检查。更好的方法是检查children
的第一个viewController
并将其转换为您要查找的viewController
。
if let destVC = segue.destination.children.first as? MyViewController
destVC.hideBottomBar = true
【讨论】:
以上是关于使用导航控制器在“prepareForSegue”中设置数据的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 prepareForSegue 方法从视图控制器推送到导航视图控制器?
将选项卡栏控制器嵌入导航控制器时的 prepareForSegue