如何清除Xamarin IOS上的堆栈?

时间:2017-09-15 16:12:35

标签: xamarin xamarin.ios xamarin.forms mvvmcross

当用户正确进行身份验证时,系统会将其定向到 HomeViewModel 。我想删除它可以返回登录屏幕的可能性,因此我创建了一个自定义演示者来删除新屏幕下方的所有屏幕。

实施如下:

 public class CustomPresenter: MvxFormsIosPagePresenter
    {
        public CustomPresenter(UIWindow window, MvxFormsApplication mvxFormsApp)
         : base(window, mvxFormsApp)
        {
        }

        public override void Show(MvxViewModelRequest request)
        {

            if (request.PresentationValues?["NavigationCommand"] == "StackClear")
            {
                var navigation = FormsApplication.MainPage.Navigation;
                Debug.WriteLine("Navigation Back Stack Count -> " + navigation.NavigationStack.Count());
                navigation.PopToRootAsync();
                Debug.WriteLine("Navigation Back Stack Count After PopToRootAsync -> " + navigation.NavigationStack.Count());
                return;
            }

            base.Show(request);
        }
    }

当身份验证过程正确完成时,我会通过使用此特殊命令传递一个包来导航到主屏幕:

LoginWithFacebookCommand.Subscribe(token => {
                Debug.WriteLine("JWT Token -> " + token);
                _userDialogs.ShowSuccess(AppResources.Login_Success);
                var mvxBundle = new MvxBundle(new Dictionary<string, string> { { "NavigationCommand", "StackClear" } });
                ShowViewModel<HomeViewModel>(presentationBundle: mvxBundle);
            });

问题是它不会改变屏幕,而是保持当前状态。怎样才能正确地做到这一点?。

我正在使用 MvvmCross 5.1.1 MvvmCross.Forms 5.1.1

非常感谢你。

2 个答案:

答案 0 :(得分:1)

据我了解,PopToRootAsync()将堆栈中的所有内容弹出到根目录。这意味着您应该在调用该方法之后将您希望导航到的视图推送到堆栈,即之后使用PushViewController(yourViewController)。此外,您应该使用MvvmCross的新IMvxNavigationService。你可以尝试一下:

var navigationService = Mvx.Resolve<IMvxNavigationService>();

LoginWithFacebookCommand.Subscribe(async (token) => {
                Debug.WriteLine("JWT Token -> " + token);

                _userDialogs.ShowSuccess(AppResources.Login_Success);

                await navigationService.Navigate<HomeViewModel>();
            });

要清除backstack,您基本上需要覆盖演示者中的Show方法,并检查是否正在调用viewmodel。如果是,则设置一个新的viewControllers数组。 (归功于@pnavk !!

public class CustomPresenter : MvxIosViewPresenter
    {
        public override void Show(IMvxIosView view, MvxViewModelRequest request)
        {
            if (MasterNavigationController != null && view.ViewModel.GetType() == typeof(HomeViewModel))
            {
                var viewController = view as UIViewController;
                MasterNavigationController.SetViewControllers(new UIViewController[] { viewController }, true);
            }
            else
                base.Show(view, request);
        }
    }

答案 1 :(得分:0)

试试这个:

navigation.SetViewControllers(new UIViewController[] { vc }, true);

vc是要设置为导航堆栈根目录的ViewController。您需要获取对它的引用,您可以使用NavigationController上的ViewControllers属性。

true - 表示您想制作动画。