如何将一个视图推送到导航栈并移除当前视图?

5
我希望将一个视图推到导航控制器堆栈中,但删除当前视图,这样当用户在下一个视图上按返回按钮时,就不会回到先前的视图。
流程方向可以是以下之一:
View X -> View 1 -> View 2 -> View 3    
View X -> View 1      ->      View 3

但是相反方向的流动总是像这样:
View X <- View 1      <-      View 3

问题是我想在View 2 Controller上处理它,在View 3上做这件事很容易覆盖后退按钮操作。View 3可以是许多不同的视图,我不想为所有这些视图覆盖后退按钮并检查堆栈的前一个控制器是否是View 2 Controller。它们都有相同的父类,所以我不能为“View 3类”控制器仅覆盖后退按钮。
我已经尝试了这个方法,以便View 2的控制器不会被添加到导航堆栈中:
//Pop controller from stack before pushing
[self.navigationController popViewControllerAnimated:YES];
[self.navigationController pushViewController:controller animated:YES];

但是一旦你点击它,它会移除视图而不是推到下一个控制器

另外一个具有相同结果的选项

NSMutableArray *viewControllers = [NSMutableArray arrayWithArray: self.navigationController.viewControllers];
[viewControllers removeObjectIdenticalTo:self];
self.navigationController.viewControllers = viewControllers;
[self.navigationController pushViewController:controller animated:YES];

你需要使用“unwind segues”。 - Fogmeister
抱歉,我忘了提到它必须与5.1兼容。 - pablobart
啊,那么唯一的方法就是弹出两次。你不能直接做你想要的事情,但你可以调用popViewController两次,或者你可以使用popToViewController并传入View 1来直接返回到View 1。 - Fogmeister
不需要。您可以从VC3中弹出两次。不确定为什么您认为需要删除VC2? - Fogmeister
这只是我的控制器设计方式,View 1 可以是许多不同的控制器,View 3 也是如此,而且 View 3 不知道 View 1 控制器是谁,除非查看堆栈。View 2 有时会出现,而其他时候流程直接从 View 1 -> View 3 进行。我只想将逻辑包含到 View Controller 2 中,这样我就不必在所有 View 3 控制器中检查前一个控制器是谁了。这就是为什么我考虑从堆栈中移除 View 2 的原因。 - pablobart
显示剩余5条评论
2个回答

16

关于你最后的那个例子,它不算是推销吧?这个可行吗?

NSMutableArray *viewControllers = [NSMutableArray arrayWithArray: self.navigationController.viewControllers];
[viewControllers removeObjectIdenticalTo:self];
[viewControllers addObject:controller];
[self.navigationController setViewControllers: viewControllers animated: YES];

如果您将控制器设置为没有自己的控制器数组,则可能会将navigationController属性设置为nil,从而使您无法立即推送新的控制器。不过,试一下也无妨。


耶!!成功了!虽然导航栏标题出现了一些奇怪的效果(因为它有一点自定义),但至少能够跳转到下一个视图并返回到正确的视图,看起来这是正确的方法。谢谢! - pablobart

1

我也有类似的用例,以下是我在 Swift 5 中提出的解决方案:

      if var controllers = self.navigationController.viewControllers {
        // finding 'View 2' to remove from navigation stack
        if let index = controllers.firstIndex(of: 'View 2') {
          controllers.remove(at: index)
        }
        controllers.append('View 3') // adding new viewController to navigation stack
        // this will update the navigation stack with system animation
        self.rootNavController.setViewControllers(controllers, animated: true)
      } else {
        // fallback scenario
        self. self.navigationController.pushViewController('View 3', animated: true)
      }

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