我的故事板中有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
的隐式展开的可选项我做错了什么?
答案 0 :(得分:6)
用以下内容替换您的代码,它至少不会崩溃。
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
}
}
}
}
答案 1 :(得分:1)
必须将barcodeInt定义为隐式解包的可选项,例如:
var barcodeInt:Int!
在这种情况下,如果在将其分配给detailItem时为nil,则由于!
,swift会认为它存在非零值且取消引用它。那是一个运行时错误。最好的办法是避免在你编写的代码中!
(例如,可以保留Apple生成的IBOutlets代码),如果可能的话,在返回隐式解包的选项之前了解有关选项的更多信息。然后,仍然谨慎使用它们。
更适合您情况的代码:
if let viewController = segue.destination as? HistoryController,
let barcodeInt = barcodeInt as? AnyObject {
viewController.detailItem = barcodeInt
} else {
NSLog("Error: expected barcodeInt to be set")
}
答案 2 :(得分:0)
我有同样的问题。逻辑是先准备序列(加载容器视图引用的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的文本!
要详细了解如何使用容器视图,请检查this S.O. answer。