Как вернуться к предыдущему контроллеру в один клик после просмотра нескольких однотипных контроллеров на iOS?

Мы используем MvvmCross 4.4.0 в нашем проекте iOS, и я столкнулся со следующей проблемой:

  • Мне нужно реализовать страницу "Элемент" со ссылкой на другую страницу "Элемент";
  • Мне нужна мгновенная обратная навигация с любой страницы "Элемент" на предыдущий контроллер (контроллер "Каталог").

Диаграмма:

Каталог --ConcreteItem--> Item1 --MoreItems--> Item2 --MoreItems-->

Item3 --BackNavButton--> Каталог.

Я делаю следующее в 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();
                }

И на самом деле это работает до тех пор, пока я не вернусь на страницу Каталог. Проблема в том, что мне нужно нажимать кнопку "Назад" столько раз, сколько я уже нажимал кнопку "Дополнительно" на странице "Элемент". Также, если мы используем пользовательскую кнопку «Назад» с таким кодом как на страницах «Каталог», так и на странице «Товар»:

  if (NavigationController?.NavigationBar?.BackItem != null)
        {
             var backbutton = new UIBarButtonItem(" ",
                                                 UIBarButtonItemStyle.Plain,
                                                 (sender, e) => { NavigationController?.PopViewController(true); })
            {
                Image = UIImage.FromBundle("BackButtonImage")
            };

            NavigationItem.LeftBarButtonItem = backbutton;
        }

затем приложение аварийно завершает работу при нажатии кнопки Назад NavButton на странице Каталог с лямбда-выражением

(sender, e) => { NavigationController?.PopViewController(true);

Удаляемый объект ItemPageViewController.

Вопрос: как правильно реализовать страницу "SingleTop" в MvvmCross?

Or

Как решить эту проблему?

P.S.: Если из MvxPresenter убрать строчку

topViewController.Dispose();

то в пользовательской лямбде будет вызываться исключение NullReferenceException.

P.P.S.: Я считаю, что проблема в том, что я не удаляю контроллер из стека навигации. Пробовал удалять контроллеры в Custom View Presenter, но, во-первых, там иногда null, и даже с проверкой null ничего не помогало.


person Oleg Kosuakiv    schedule 25.06.2018    source источник
comment
Каталог является отправной точкой вашего приложения?   -  person Mark Verkiel    schedule 25.06.2018
comment
@Pilatus, нет, это не так.   -  person Oleg Kosuakiv    schedule 25.06.2018


Ответы (1)


UINavigationController имеет функцию PopToViewController(UIViewController viewController, bool animated);

Вместо того, чтобы удалять все ViewController, когда представления имеют один и тот же тип, вы можете перейти к каталогу ViewController при нажатии кнопки «Назад».

UINavigationController имеет свойство ViewControllers, которое мы можем использовать, чтобы найти CatalogueViewController.

Поскольку вы используете MvvmCross, мы проверим тип ViewModel.

var catalogueController = NavigationController.ViewControllers.First(c => 
    ((IMvxIosView)c).ViewModel.GetType() == typeof(CatalogueViewModel));

Теперь вы можете использовать функцию PopToViewController для закрытия всех представлений до CatalogueController

CurrentNavigationController.PopToViewController(catalogueController, true);
person Mark Verkiel    schedule 26.06.2018
comment
Спасибо, я сделал это, и это сработало. Единственным недостатком является то, что мне пришлось использовать пользовательскую кнопку «Назад» и указать конкретный тип родительского контроллера, который является зависимостями. Но я действительно хотел иметь общее решение. - person Oleg Kosuakiv; 26.06.2018
comment
Вы можете создать интерфейс, реализовать его на ViewModel и найти ViewModel, который реализует этот интерфейс, и перейти к этому ViewController. Тогда это решение будет более общим. - person Mark Verkiel; 26.06.2018