Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to push a view to the navigation stack and remove the current one?

I would like to push a view into the navigation controller stack but remove the current one so when the users press back on the next view it does't take them to the previous view.

The flow in one direction could be one of these:

View X -> View 1 -> View 2 -> View 3    
View X -> View 1      ->      View 3

But the flow in the oposite direction is always like this:

View X <- View 1      <-      View 3

The problem is that I want to handle it on the View 2 Controller, doing it on the View 3 is easy overriding the back button action. The View 3 can be a lot of different views and I don't want to override the back button for all of them and check if the previous controller of the stack is the View 2 Controller. They all have the same parent class, so I can't override the back button for just the 'View 3 class' controllers.

I've tried this so the controller of the View 2 is not added into the navigation stack:

//Pop controller from stack before pushing
[self.navigationController popViewControllerAnimated:YES];
[self.navigationController pushViewController:controller animated:YES];

But once you pop it removes the view and doesn't push to the next controller

Other option with the same result

NSMutableArray *viewControllers = [NSMutableArray arrayWithArray: self.navigationController.viewControllers];
[viewControllers removeObjectIdenticalTo:self];
self.navigationController.viewControllers = viewControllers;
[self.navigationController pushViewController:controller animated:YES];
like image 340
pablobart Avatar asked Jan 18 '13 22:01

pablobart


People also ask

Is UINavigationController a UIViewController?

A UINavigationController does a lot of this tedious work for you. As mentioned, it contains a stack of UIViewControllers. It will create a navigation bar at the top that will allow you to easily go back up the hierarchy of view controllers.

What is UINavigationController?

Overview. A navigation controller is a container view that can manage the navigation of hierarchical contents. The navigation controller manages the current displaying screen using the navigation stack. Navigation stack can have “n” numbers of view controllers.


2 Answers

In regards to your last example that isn't pushing, does this work?

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

Since you set the controllers to an array of controllers without yourself, you might be setting your navigationController property to nil, making you unable to push the new one immediately after. It doesn't hurt to try, anyways.

like image 67
Metabble Avatar answered Oct 10 '22 00:10

Metabble


I also had a similar use-case and this was the solution that I came up in 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)
      }
like image 38
Charitha Basnayake Avatar answered Oct 09 '22 23:10

Charitha Basnayake