[self.navigationController popToViewController:VC2 animated:NO];崩溃

5

你好,我正在开发一款应用程序,需要进行以下操作:

  1. UIViewController1 跳转到 UIViewController2
  2. UIViewController2 跳转到 UIViewController3
  3. UIViewController3 跳转到 UIViewController4
  4. UIViewController4 返回到 UIViewController2

我使用的是 UINavigationController。当我使用 [self.navigationController pushViewController:VC2 animated:NO];[self.navigationController popViewControllerAnimated:NO]; 时,一切正常工作。

但当我从 UIViewController4 使用 [self.navigationController popToViewController:VC2 animated:NO]; 时,应用程序会终止,并显示错误信息:Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to pop to a view controller that doesn't exist.'

以下是我如何弹出 UIViewController2 的代码

for (UIViewController *vc in self.navigationController.viewControllers) {
            if ([vc isKindOfClass:[ViewController2 class]]) {
                UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
                ViewController2 *VC2 = [storyboard instantiateViewControllerWithIdentifier:@"ViewController2"];
                [self.navigationController popToViewController:VC2 animated:NO];
            }
        }

当我打印导航数组时,它显示堆栈中的UIViewController2。 我从编辑器中添加了UINavigationController->嵌入->导航控制器。
请问有谁能告诉我为什么会发生这种情况?我尝试搜索这个问题,但没有找到有用的信息。

我认为你的UINavigationController中没有VC2实例。也许你有两个不同的UIViewController2实例?尝试在for-each循环中调用[[self.navigationController viewControllers] indexForObject:VC2]; 和[VC isKindOfClass:[UIViewController2 class]]来检查是否正确。 - Szu
你需要跳转到导航栈中的一个UIViewController。你正在尝试弹出一个新分配的导航控制器。 - The dude
3个回答

18

在这里,您实例化了一个新的VC2视图控制器实例,这不是您在导航视图控制器堆栈上拥有的实例!

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
            ViewController2 *VC2 = [storyboard     instantiateViewControllerWithIdentifier:@"ViewController2"];

所以你必须在实例中找到正确的一个

[[self.navigationController] viewControllers]

解决方案1:(正如iDev所说的,在堆栈中跳转到第二个视图控制器。如果您知道它是第二个视图控制器,则使用此选项)

Solution 1: (as iDev said, jump to second view controller on stack, use this if you know it is the second one)

[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];

解决方案2:(通常在堆栈上向后返回2级)

NSUInteger ownIndex = [self.navigationController.viewControllers indexOfObject:self];
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:ownIndex - 2] animated:YES];

很好的答案,非常适合我的需求。 - Rahul K Rajan

9

这是你的代码:

for (UIViewController *vc in self.navigationController.viewControllers) {
    if ([vc isKindOfClass:[ViewController2 class]]) {
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
        ViewController2 *VC2 = [storyboard instantiateViewControllerWithIdentifier:@"ViewController2"];
        [self.navigationController popToViewController:VC2 animated:NO];
    }
}

您可能已经注意到,vc是一种ViewController2,而且已经在导航堆栈中了。您创建的VC2实例属于ViewController2,但从未进入导航堆栈。
请看异常信息:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to pop to a view controller that doesn't exist.'

因此,您试图返回到一个未推入导航堆栈的视图控制器,这会导致崩溃。
您需要返回到已经在堆栈中的视图控制器,也就是vc
for (UIViewController *vc in self.navigationController.viewControllers) {
    if ([vc isKindOfClass:[ViewController2 class]]) {
        [self.navigationController popToViewController:vc animated:NO];
    }
}

5
尝试使用以下代码将您的视图控制器弹出到第二个位置:

尝试使用此行代码将您的视图控制器弹出至第二个位置

  [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];

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