在我的故事板中,我有一个视图控制器,我还有一个导航控制器和另一个名为HistoryController的视图控制器。导航控制器和HistroyController有一个关系"根视图控制器"
我的第一个视图控制器上有一个按钮,该按钮有一个推送导航控制器。
我在第一个视图控制器中有这个代码来准备segue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let viewController = segue.destination as? HistoryController {
viewController.detailItem = barcodeInt as AnyObject
}
}
我的问题是当我运行我的代码并按下第一个控制器中的按钮时,我收到此错误:
Could not find a navigation controller for segue 'HistorySegue'. Push segues can only be used when the source controller is managed by an instance of UINavigationController.'
我的问题是,为什么我会收到此错误,我该如何解决?
我试过以下
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let navVC = segue.destinationViewController as? UINavigationController{
if let historyVC = navVC.viewControllers[0] as? HistoryController{
historyVC.detailItem = barcodeInt as AnyObject
}
}
}
我也试过
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let nav = segue.destination as? UINavigationController {
if let vc = nav.visibleViewController as? HistoryController {
vc.detailItem = barcodeInt as AnyObject
}
}
}
我仍然得到同样的错误:
Could not find a navigation controller for segue 'HistorySegue'. Push segues can only be used when the source controller is managed by an instance of UINavigationController.'
答案 0 :(得分:9)
您需要将源视图控制器嵌入到导航控制器中,或将segue类型从推送更改为其他内容。此外,尝试将目标控制器转换为UINavigationController,以防止在初始控制器之后出现另一个错误:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let navVC = segue.destinationViewController as? UINavigationController{
if let historyVC = navVC.viewControllers[0] as? HistoryController{
historyVC.detailItem = barcodeInt as AnyObject
}
}
}
看看它是否适合你。
编辑:更新了上面的代码。
答案 1 :(得分:1)
你的问题不在你的代码中,没关系,它在你的故事板中。
如果您想从ViewController推送到HistoryVC,ViewController应嵌入UINavigationController,而不是HistoryVC(它将与ViewController的关系隐式嵌入)。
这样做的原因是推送的VC必须嵌入到UINavigationController中,正在推送的vc本身是嵌入式的,因为它被添加到UINavigationController的堆栈中。
如果初始ViewController不在UINavigationController中,则推送的ViewController(HistoryVC)没有堆栈。基本上,你在UINavigationController中嵌入了你的堆栈(你的第一个ViewController)的起点。
如果你想在新的堆栈中启动一个新的堆栈,你可以在新的UINavigationController中嵌入下一个视图控制器,但是你需要以模态方式进行转换。
答案 2 :(得分:1)
试试这个:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let navVC = segue.destinationViewController as? UINavigationController{
if let historyVC = navVC.childViewControllers[0] as? HistoryController{
historyVC.detailItem = barcodeInt as AnyObject
}
}
}
答案 3 :(得分:1)
您应该使用show
segue而不是push
segue。
show segue会尽可能将下一个viewController推送到第一个viewcontroller的navigationController堆栈中,否则它将使用modalPresent
来显示下一个viewController。
如果你将第一个viewController嵌入到UINavigationController中,并且仍然保留你的导航控制器,那么你使用push
segue,你会得到一个例外:
***由于未捕获的异常终止应用程序' NSInvalidArgumentException',原因:'不支持推送导航控制器'
将您的segue从push
简单地更改为show
以适合您的情况。
答案 4 :(得分:0)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let nav = segue.destination as? UINavigationController {
if let vc = nav.visibleViewController as? HistoryController {
vc.detailItem = barcodeInt as AnyObject
}
}
}
答案 5 :(得分:0)
如错误所示“如果您的源(第一个viewController)没有嵌入navigationController中,则无法使用push segue。
您需要将segue的类型从“push”更改为“presentModally” - 通常应该可以。 您仍然可以使用navigationController但不能使用push-push仅在NavigationController内部工作。
答案 6 :(得分:0)
在我的故事板中,我有一个视图控制器,我还有一个导航控制器和另一个名为HistoryController的视图控制器。导航控制器和HistroyController有一个关系"根视图控制器"
我的第一个视图控制器上有一个按钮,该按钮有一个推送导航控制器。
现在这是你的问题。在您的故事板中,您应该rootViewController
和UINavigationController
之间以及不与FirstViewController
之间存在HistoryController
关系。然后,FirstViewController
中的按钮应与HistoryController
建立推送连接。见下图:
此外,应用入口点应为UINavigationController
(只需拖动左侧小箭头或选择UINavigationController
,然后选择右侧底板检查Is initial controller
)。
答案 7 :(得分:0)
问题在于您尝试使用UIViewController
而不是UINavigationController
推送segue。
正如您所看到的,第一个视图控制器正在向第二个视图控制器显示segue,它包含在导航控制器中。
这样,当您激活segue时,只需使用以下代码访问您的UIViewController
子类:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let historyVC = segue.destination as? HistoryController {
// do what you need to.
}
}
如果您不需要专门针对UINavigationController
单独HistoryController
,则可以删除HistoryController
以上的<path id="#ondasAceite" ...
,并使用附加到第一个视图控制器的那个。
答案 8 :(得分:0)
要使用push segue,ViewController需要嵌入到NavigationController中。如果您不希望ViewController成为NavigationController的视图控制器堆栈的一部分,您可以使用以下命令在HistoryController中删除:
override func awakeFromNib() {
navigationController?.setViewControllers([self], animated: false)
}
另一种方法是从ViewController到NavigationController的segue不是push segue,例如如果要控制NavigationController在屏幕中显示的方式,请显示模态或自定义。
答案 9 :(得分:0)
您是否尝试过检查标识符?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let nav = segue.destination as? UINavigationController where segue.identifier == "yourSegueIdentifierSetInTheStoryboard"{
if let vc = nav.visibleViewController as? HistoryController {
vc.detailItem = barcodeInt as AnyObject
}
}
}