MvvmCross 迁移导致 Xamarin Custom iOS View Presenter 问题

MvvmCross migration causing a Xamarin Custom iOS View Presenter issue

在创建 CustomIosViewPresenter(MvxIosViewPresenter 类型)时,在 MVVMCross 5.x 中,有一个 Show 覆盖,我可以使用它来获取 IMvxIosView以便使用 ViewModel 中的 PresentationValues 更新 UIViewController 表示样式。

我有这段代码并且有效:

// Worked before
public override void Show(IMvxIosView view, MvvmCross.ViewModels.MvxViewModelRequest request)
{
    if (request.PresentationValues != null)
    {
        if (request.PresentationValues.ContainsKey("NavigationMode") &&
            request.PresentationValues["NavigationMode"] == "WrapInModalWithNavController")
        {
            var vc = view as IModalPresentation;
            vc.ModalPresentationAttribute = new MvxModalPresentationAttribute
            {
            WrapInNavigationController = true,
            ModalPresentationStyle = UIModalPresentationStyle.OverFullScreen,
            ModalTransitionStyle = UIModalTransitionStyle.CoverVertical
            };
        }
    }
    base.Show(view, request);
}

但是在迁移到 MvvmCross 7.1 之后,旧的覆盖不再起作用,我必须改用它,但是没有视图传递到 Show 覆盖中,我如何获得它? 我在下面尝试了这段代码,但是 view 为 null 并且无法以这种方式转换 var view = viewType as IMvxIosView;

// Doesn't work now
public override Task<bool> Show(MvxViewModelRequest request)
{
    if (request.PresentationValues != null)
    {
        if (request.PresentationValues.ContainsKey("NavigationMode") &&
            request.PresentationValues["NavigationMode"] == "WrapInModalWithNavController")
        {
            var viewsContainer = Mvx.IoCProvider.Resolve<IMvxViewsContainer>();
            var viewType = viewsContainer.GetViewType(request.ViewModelType);
            var view = viewType as IMvxIosView;
            
            var vc = view as IModalPresentation;
            vc.ModalPresentationAttribute = new MvxModalPresentationAttribute
            {
                WrapInNavigationController = true,
                ModalPresentationStyle = UIModalPresentationStyle.OverFullScreen,
                ModalTransitionStyle = UIModalTransitionStyle.CoverVertical
            };
        }
    }
    return base.Show(request);
}

我需要这个的原因是因为如果没有这个功能,当我关闭需要这个的视图控制器的特殊流程时,它不会关闭该流程中的所有视图控制器,它一次只关闭其中一个。

如果你想在模态 ViewController 中导航,你通常会用 MvvmCross 做的是首先添加一个 MvxModalPresentationAttribute 到模态,它将承载你设置的其余导航 WrapInNavigationControllertrue.

对于 children,它只是常规 child 导航,不需要任何属性。

如果您随后想要控制模态框的弹出方式,您可以创建自己的 MvxPresentationHint 并使用 AddPresentationHintHandler.

在演示者中注册它

然后您将在您的 ViewModel 中要更改演示文稿的位置调用 NavigationService.ChangePresentation(your hint)

至于 Presentation Hint,它可能应该只调用 CloseModalViewControllers,这可能会执行您想要的操作。

TLDR:感受追随你的开发者并以正确的方式构建东西

所以我深入研究 MvvmCross MvxIosViewPresenter source code 并能够使用这个新的覆盖 CreateOverridePresentationAttributeViewInstance()

我需要请求对象来查看表示值,因此我更新了 Show 函数,该函数在另一个覆盖之前被调用,如下所示:

MvxViewModelRequest _request;
public override Task<bool> Show(MvxViewModelRequest request)
{
    _request = request;
    return base.Show(request);
}

而且我能够通过这种方式获得 ViewController,以便有选择地将其显示为模态:

{
    var view = base.CreateOverridePresentationAttributeViewInstance(viewType);
    if (_request.PresentationValues.ContainsKey("NavigationMode") &&
_request.PresentationValues["NavigationMode"] == "WrapInModalWithNavController")
    {
        var vc = view as IModalPresentation;

        vc.ModalPresentationAttribute = new MvxModalPresentationAttribute
        {
            WrapInNavigationController = true,
            ModalPresentationStyle = UIModalPresentationStyle.OverFullScreen,
            ModalTransitionStyle = UIModalTransitionStyle.CoverVertical
        };
        return vc;
    }                    
    return view;
}

然后关闭模式是另一个挑战,我能够使用 TryCloseViewControllerInsideStackChangePresentation 覆盖

来解决这个问题