Ios MvvmCross-Tabs控制器是否包装到UINavigation控制器中?

Ios MvvmCross-Tabs控制器是否包装到UINavigation控制器中?,ios,xamarin.ios,uinavigationcontroller,mvvmcross,Ios,Xamarin.ios,Uinavigationcontroller,Mvvmcross,我使用的是Xamarin.iOS和MvvmCross 5.x。我的根视图是Tabs控制器,我希望任何显示子对象的请求都会强制在选项卡外部(而不是内部)进行堆栈导航 因此,我将我的根视图定义如下: [MvxFromStoryboard] [MvxRootPresentation(WrapInNavigationController = true)] public partial class HomeView : MvxTabBarViewController<HomeViewModel>

我使用的是Xamarin.iOS和MvvmCross 5.x。我的根视图是Tabs控制器,我希望任何显示子对象的请求都会强制在选项卡外部(而不是内部)进行堆栈导航

因此,我将我的根视图定义如下:

[MvxFromStoryboard]
[MvxRootPresentation(WrapInNavigationController = true)]
public partial class HomeView : MvxTabBarViewController<HomeViewModel>
但是,在尝试设置控制器
base.SetWindowRootViewController(\u rootViewController)
时,此代码在MvvmCross的深处失败,出现以下错误:

System.NullReferenceException: Object reference not set to an instance of an object\n  
at MvvmCross.iOS.Views.Presenters.MvxIosViewPresenter.CloseTabBarViewController () [0x00036] in <861dee92d7924acc93d876339b4b95f9>:0  
at MvvmCross.iOS.Views.MvxTabBarViewController.ViewWillDisappear (System.Boolean animated) [0x0001f] in <861dee92d7924acc93d876339b4b95f9>:0 
at (wrapper managed-to-native) ObjCRuntime.Messaging:void_objc_msgSend_IntPtr (intptr,intptr,intptr)  
at UIKit.UIWindow.set_RootViewController (UIKit.UIViewController value)
System.NullReferenceException:对象引用未设置为对象的实例\n
在MvvmCross.iOS.Views.Presenters.MvxIosViewPresenter.CloseTabBarViewController()[0x00036]中:0
在MvvmCross.iOS.Views.MvxTabBarViewController.viewwill消失(System.Boolean动画)[0x0001f]中:0
在(包装器管理为本机)objc运行时。消息传递:void_objc_msgSend_IntPtr(IntPtr,IntPtr,IntPtr)
在UIKit.UIWindow.set_RootViewController(UIKit.UIViewController值)处

如何在不为根视图创建额外的ViewModel和View的情况下实现我的目标(我不喜欢这种方法,因为在这种情况下Android会崩溃)

我创建了这个示例,它完全包含了您需要的内容:

当我在寻找解决方案时,MvvmCross的伙计们将框架更新为版本
5.1.1
(我使用的是
5.1.0
)。Ios presenter逻辑已正确更新
WrapInNavigationController
(之前,如果是选项卡,则忽略它)。不幸的是,
ShowChildViewController
在那之后出现了故障,出现了
InvalidCastException
,但我能够通过将根导航控制器的优先级设置为高于选项卡控制器来处理这一问题

    protected override void ShowChildViewController(UIViewController viewController, MvxChildPresentationAttribute attribute, MvxViewModelRequest request)
    {
        if (viewController is IMvxSplitViewController)
            throw new MvxException("A SplitViewController cannot be presented as a child. Consider using Root instead");

        if (ModalViewControllers.Any())
        {
            if (ModalViewControllers.LastOrDefault() is UINavigationController modalNavController)
            {
                PushViewControllerIntoStack(modalNavController, viewController, attribute.Animated);
                return;
            }

            throw new MvxException($"Trying to show View type: {viewController.GetType().Name} as child, but there is currently a plain modal view presented!");
        }

        // this logic goes first for the root controller 
        if (MasterNavigationController != null)
        {
            PushViewControllerIntoStack(MasterNavigationController, viewController, attribute.Animated);
            return;
        }

        // then try to show child for the tabs
        if (TabBarViewController != null && TabBarViewController.ShowChildView(viewController))
        {
            return;
        }

        base.ShowChildViewController(viewController, attribute, request);
    }

我希望它能节省别人的时间。

谢谢你的努力,这个应用程序正是我想要的。不幸的是,您正在使用mvvmcross已经包含的一些手动选项卡创建逻辑(我想坚持使用该逻辑)和我不清楚的自定义ios演示者技巧:1。为什么在
ShowRootViewController
中不调用基类方法?2.为什么用相同的方法调用
SetWindowRootViewController
?3.为什么在
ShowChildViewController
中,您必须设置
TabBarViewController
(基本上每次当您想让孩子看到您的演示者这样做时)。请澄清哦。。。我打开了原始的mvvmcross代码并得到了答案-代码取自那里:)我已经测试了解决方案,当使用
IMvxNavigationService
通过简单的调用导航方法创建选项卡时,我无法通过mvvmcross将其用于选项卡创建。我不完全理解您想要什么。使用这段代码,您不需要预先实例化viewmodel,而是让MvvmCross为您实例化:您只需要更改CreateTabFor签名以接受表示所需viewModelType的类型参数。然后,调用该方法:CreateTabFor(0,“My tab”,null,typeof(ChildViewModel))@DominikR我将很快用新版本的MvvmCross更新存储库代码。如果希望视图显示为MasterNavigationController的子视图,则应覆盖TabBarController中的
ShowChildView
,并返回false。很抱歉没有相关文档,我们将更新网站:)@nmilcoff是的,即使没有自定义演示者,这种方法也可以使用,谢谢!现在还不清楚为什么TabViewController的showChildView会给我一个无效的强制转换异常,它是5.1.1的一个大异常吗?它确实是一个bug,代码应该返回false而不是break。我会马上修好的,谢谢你让我知道!
    protected override void ShowChildViewController(UIViewController viewController, MvxChildPresentationAttribute attribute, MvxViewModelRequest request)
    {
        if (viewController is IMvxSplitViewController)
            throw new MvxException("A SplitViewController cannot be presented as a child. Consider using Root instead");

        if (ModalViewControllers.Any())
        {
            if (ModalViewControllers.LastOrDefault() is UINavigationController modalNavController)
            {
                PushViewControllerIntoStack(modalNavController, viewController, attribute.Animated);
                return;
            }

            throw new MvxException($"Trying to show View type: {viewController.GetType().Name} as child, but there is currently a plain modal view presented!");
        }

        // this logic goes first for the root controller 
        if (MasterNavigationController != null)
        {
            PushViewControllerIntoStack(MasterNavigationController, viewController, attribute.Animated);
            return;
        }

        // then try to show child for the tabs
        if (TabBarViewController != null && TabBarViewController.ShowChildView(viewController))
        {
            return;
        }

        base.ShowChildViewController(viewController, attribute, request);
    }