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

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

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

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

47506 次浏览

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

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

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

在旧版本的 Swift 和 UIKit 中,代码稍有不同:

let destinationNavigationController = segue.destinationViewController as UINavigationController
let targetController = destinationNavigationController.topViewController
  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. Edit the identifier segue to "showNavigationController"

screenshot

  1. In your ReceiveViewController add

this

var data : String = ""


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

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

以下是 Swift 3的答案:

let svc = segue.destination as? UINavigationController


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

使用 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
}
}

Swift 3中的一句话:

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

在 Swift 5里

如果您不仅必须从 SourceViewController 转移到嵌入在 UINavigationController 中的 DestinationViewController,而且还必须转移到一个新的故事板,那么请执行以下操作..。

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

  2. 转到 NavigationViewController,使用身份检查器给它一个故事板 ID,“ DestinationNavVC”就可以了。

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

  4. (可选)如果你需要附加数据和你的继续,并将其发送到 DestinationViewController 中的属性,你可以在 SourceViewController 文件中的 Ready-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,上面的方法可以正常工作(w/o 步骤3)

  5. 在按钮的 IBAction Outlet 方法中,你用来启动引导的方法是这样的:

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

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

像这样:

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)

希望能有所帮助。

跳过 UINavigationController检查是一个好主意,因为可能有多个 segues使用 navigationController,因此将进入每个使用 navigationControllersegue的检查。一个更好的方法是检查第一个 viewControllerchildren和铸造它作为 viewController你正在寻找。

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