Reputation: 31333
We have a sequence of screens that navigate in order...
BaseViewController -> A -> B -> BaseViewController
Each screen uses NavigationController.PushViewController
to go from...Base->A, A->B. So each subsequent screen is placed in the navigation stack.
So if you are on A and you click 'back', then it goes back one screen. This works well as it is controlled by the NavigationController.
However, when you are on screen B, 'back' should to back to the BaseViewController.
Instead it goes (as designed by Apple) back to A. Is there a way to intercept the 'back' button on B so we can instead use NavigationController.PopToViewController to send the user back to BaseViewController?
Upvotes: 0
Views: 1536
Reputation: 31333
Thanks for all the answers. @Cole Xia put me on the right path for our scenario. His technique works, and the following works as well.
Here is the Xamarin code. The technique is to replace the current list of ViewControllers with a new one. Then when 'back' is hit on B, it goes right back to BaseViewController.
var viewControllers = new UIViewController[] { NavigationController.ViewControllers[0], new B() };
NavigationController.SetViewControllers(viewControllers, false);
Upvotes: 0
Reputation: 4669
If I understand correctly you want to pop to root view controller from a certain top view controller. One way to do it would be to create a subclass of UINavigationController
and override popViewController
method where you would check what you have on top at the moment and decide to pop to root or not. Here's an example:
open class CustomNavigationController: UINavigationController {
override open func popViewController(animated: Bool) -> UIViewController? {
if topViewController is BViewController {
return popToRootViewController(animated: animated)?.last
} else {
return super.popViewController(animated: animated)
}
}
}
Upvotes: 1
Reputation: 14463
LeftBarButtonItem
,and handle the back
event .ViewDidLoad
in Bthis.NavigationItem.LeftBarButtonItem =
new UIBarButtonItem("back", UIBarButtonItemStyle.Plain, (sender,e) => {
UIViewController baseVC = NavigationController.ViewControllers[NavigationController.ViewControllers.Length - 3];
NavigationController.PopToViewController(baseVC, true);
});
ViewDidLoad
in BList<UIViewController> list = NavigationController.ViewControllers.ToList<UIViewController>();
list.RemoveAt(list.Count-2);
NavigationController.ViewControllers = list.ToArray();
Upvotes: 1
Reputation: 1079
You can do something like this in B's viewDidAppear
function:
guard let navigationController = self.navigationController else {
return
}
navigationController.viewControllers.remove(at: navigationController.viewControllers.count - 2)
This will remove A from the stack, and allow you to go back to BaseViewController from B.
Upvotes: 1
Reputation: 17725
C
which is a subclass of Base
A
as a child view controller to C
D
which is a subclass of Base
B
as a child view controller to D
C
to D
Upvotes: 0