We are using MvvmCross 4.4.0 on the our iOS project and I faced the following problem:
Diagram:
Catalogue --ConcreteItem--> Item1 --MoreItems--> Item2 --MoreItems-->
Item3 --BackNavButton--> Catalogue.
I am doing the following thing in the Custom ViewPresenter:
var topViewController = ParentRootViewController.TopViewController;
ParentRootViewController.PushViewController(currentViewController, needAnimation);
if (topViewController.GetType() == currentView.GetType()
&& /*Logic to determine if its correct view types*/)
{
topViewController.RemoveFromParentViewController();
topViewController.Dispose();
}
And actually it works until I didn't return to the "Catalogue" page. The problem is that I need to click back button so many times I had clicked "More" button on "Item" page. Also if we use custom back button with such code in both "Catalogue" and "Item" pages:
if (NavigationController?.NavigationBar?.BackItem != null)
{
var backbutton = new UIBarButtonItem(" ",
UIBarButtonItemStyle.Plain,
(sender, e) => { NavigationController?.PopViewController(true); })
{
Image = UIImage.FromBundle("BackButtonImage")
};
NavigationItem.LeftBarButtonItem = backbutton;
}
then app crashes when clicking "Back" NavButton on "Catalogue" page with in lambda
(sender, e) => { NavigationController?.PopViewController(true);
The disposed object ItemPageViewController.
The question is : How to correctly implement "SingleTop" page in MvvmCross?
Or
How to fix this problem?
P.S.: If from MvxPresenter remove line
topViewController.Dispose();
then in custom lambda would throw NullReferenceException.
P.P.S.: I believe it the problem that I don't remove controller from navigation stack. I have tried to remove controllers in Custom View Presenter, but, firstly, it is null there sometimes, and even with null check nothing helped.
UINavigationController
has a function PopToViewController(UIViewController viewController, bool animated);
Instead of removing every ViewController
when the views are of the same type, you could pop to the ViewController
Catalogue when the backbutton is pressed.
UINavigationController
has a property ViewControllers
that we can use to find CatalogueViewController
.
Since you're using MvvmCross
we'll check for the ViewModel
type.
var catalogueController = NavigationController.ViewControllers.First(c =>
((IMvxIosView)c).ViewModel.GetType() == typeof(CatalogueViewModel));
Now you can use the function PopToViewController
to close all the views untill CatalogueController
CurrentNavigationController.PopToViewController(catalogueController, true);