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];
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.
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.
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.
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)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With