斯威夫特3 – 准备癫痫

我的故事板中有3个场景。 我的初始View Controller是一个导航控制器,然后有一个关系根视图控制器到UI ViewController(视图控制器a),然后我有一个从ViewController中的按钮到第三个ViewController(视图控制器b)的推送segue现场。 我给push segue一个标识符。 现在我试图在第二个视图控制器(视图控制器a)中准备我的segue,如下所示:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "HistorySegue" { if let viewController = segue.destination as? HistoryController { viewController.detailItem = barcodeInt as AnyObject } } } 

但是,当我运行此代码并按下控制器中的按钮时,我收到以下错误:

致命错误:尝试桥接包含nil的隐式未包装的可选项

我究竟做错了什么?

用以下代码替换您的代码,它至少不会崩溃。

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "HistorySegue" { if let viewController = segue.destination as? HistoryController { if(barcodeInt != nil){ viewController.detailItem = barcodeInt as AnyObject } } } } 

必须是barcodeInt被定义为隐式解包的可选项,如:

var barcodeInt:Int!

在这种情况下,如果将它分配给detailItem则为nil,因为! ,swift接受你的话,那里有一个非零值,并取消引用它。 那是一个运行时错误。 你最好的选择是避免! 在您编写的代码中(例如,可以保留Apple生成的IBOutlets代码),如果可能的话,在返回隐式解包的选项之前了解有关选项的更多信息。 然后,仍然谨慎地使用它们。

更安全的代码适用于您的情况:

 if let viewController = segue.destination as? HistoryController, guard let barcodeInt = barcodeInt as? AnyObject else { NSLog("Error: expected barcodeInt to be set") return } viewController.detailItem = barcodeInt } 

我遇到过同样的问题。 逻辑是首先准备segue(加载容器视图引用的UIViewController),将其分配给变量,然后在viewDidLoad()中使用它。 这段代码应该有效:

Swift 4.2

 // usually an IBoutlet var viewController: HistoryController! override func viewDidLoad() { super.viewDidLoad() viewController.detailItem = barcodeInt as AnyObject } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "HistorySegue" { viewController = segue.destination as! HistoryController } } 

detailItem可能被定义为HistoryController中的IBoutlet,它取决于OP代码。 在我的例子中,我有两个简单的容器视图,每个视图都有一个标签,这是主视图控制器类的最终工作代码:

 import UIKit class ViewController: UIViewController { @IBOutlet var firstView: ReusableViewController! @IBOutlet var secondView: ReusableViewController! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. firstView.myLabel.text = "My 1st reuse!!!" secondView.myLabel.text = "And that's the 2nd!" } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if (segue.identifier == "segueFirstView") { firstView = (segue.destination as! ReusableViewController) } if (segue.identifier == "segueSecondView") { secondView = (segue.destination as! ReusableViewController) } } } 

有了这个,我终于可以直接从主控制器更改两个不同的UILabel的文本!

有关如何使用容器视图的详细说明,可以查看此SO答案 。