【问题标题】:how to check if controller is already on navigationcontroller viewcontrollers stack?如何检查控制器是否已经在导航控制器视图控制器堆栈上?
【发布时间】:2015-02-25 19:16:58
【问题描述】:

我收到此错误:

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

【问题讨论】:

    标签: ios swift uinavigationcontroller uitabbar


    【解决方案1】:

    您似乎将同一个控制器推送到导航堆栈。您不能将视图控制器推送到堆栈中已经存在的堆栈上。可能是你多次调用tabSelected()方法,所以你应该确保它不会被多次调用。

    防止崩溃的一个好做法是弹出现有的控制器, 已经在堆栈中。因此,每当您离开视图控制器时,您都应该执行self.navigationController?.popToViewController(myViewController, animated: true) 之类的操作。

    或者您可以执行以下操作来检查您的控制器已经在堆栈中:

     if (self.navigationController?.topViewController.isKindOfClass(ViewController) != nil) {
    
    }
    

    针对您的特定情况,请执行以下操作:

    if(mainNavigationController.topViewController.isKindOfClass(ProfileViewController) != nil) {
    
        }
    

    【讨论】:

    • 那么,在 ProfileViewController 中,当我离开控制器时我应该 self.navigationController?.popToViewController(ProfileViewController, animated: true) 吗?在视图中消失了吗? viewDidUnload?
    • 如果您在viewDidDisappear 中弹出视图控制器,可能会导致问题。当您点击导航栏中的取消或返回按钮时,您通常会使用popViewController。如果您正在使用 UITabbarController 构建标签栏基本应用程序,您应该使用tabBarVC.selectedIndex = YOUR_INDEX 在控制器之间切换。如果你没有使用 UITabbarController,你应该实现一个 UITabbarDelegate,并在它的委托方法中插入子视图,见this example
    【解决方案2】:

    您可以检查导航控制器的viewControllers 属性。

    if contains(mainNavigationController.viewControllers, controller) {
      // move it
    } else {
      // push it
    }
    

    【讨论】:

    • 对于更新的 Swift 版本,您可能需要反转它:mainNavigationController.viewControllers.contains { $0 == controller }
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-11
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多