如何检查控制器是否已经在导航控制器的视图控制器堆栈中?

4
我遇到了这个错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing the same view controller instance more than once is not supported

如何检查控制器是否已经存在于堆栈中,而不是将该控制器推入堆栈而是移动到该控制器?

以下是一些代码,我正在基于选项卡选择推送一个控制器:

func tabSelected(tab: String) {
    switch tab{
    case "payment":
        mainNavigationController.popToViewController(myAccountViewController, animated: true)
    break
    case "delivery":
        mainNavigationController.pushViewController(deliveryViewController, animated: true)
        break
    case "service":
        mainNavigationController.pushViewController(serviceViewController, animated: true)
        break
    case "profile":
        mainNavigationController.pushViewController(profileViewController, animated: true)
        break
    default:
        break
    }
}
3个回答

4
你可以检查导航控制器的viewControllers属性。
if contains(mainNavigationController.viewControllers, controller) {
  // move it
} else {
  // push it
}

1
您可能需要对Swift的更新版本进行反转:mainNavigationController.viewControllers.contains { $0 == controller } - Ian MacDonald

4
看起来你正在将同一个控制器推送到导航栈中。不能将已经存在于栈中的视图控制器再次推送到栈中。可能是因为你多次调用了tabSelected()方法,所以请确保它不会被多次调用。
防止崩溃的一种好的做法是弹出已存在于栈中的控制器。因此,当你离开你的视图控制器时,应该像这样做:self.navigationController?.popToViewController(myViewController, animated: true)
或者你可以执行以下操作来检查你的控制器是否已经在栈中:
 if (self.navigationController?.topViewController.isKindOfClass(ViewController) != nil) {

}

针对您的情况,请按照以下步骤操作:
if(mainNavigationController.topViewController.isKindOfClass(ProfileViewController) != nil) {

    }

那么,在ProfileViewController中,当我离开控制器时,我应该在viewDidDisappear或viewDidUnload中使用self.navigationController?.popToViewController(ProfileViewController, animated: true)吗? - Sam Luther
如果你在 viewDidDisappear 中弹出(view controller),可能会导致问题。通常情况下,当你点击导航栏中的取消或返回按钮时,应该执行 popViewController。如果你正在构建一个带有UITabbarController的基本应用程序,则应该执行 tabBarVC.selectedIndex = YOUR_INDEX 来在控制器之间切换。如果不使用UITabbarController,则应该实现UITabbarDelegate,并在其代理方法中插入子视图,请参见此示例 - ztan

1

要检查视图控制器是否存在于导航堆栈中,您可以使用以下方法。这将在Swift 5中编译:

    if let stack = self.navigationController?.viewControllers {
      for vc in stack where vc.isKind(of: SomeViewController.self) {
        debugPrint("exists")
      }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接