首先,我假设您正在尝试为 iOS 实现此功能。对于 Android,您可以简单地使用导航抽屉。
iOS 上的示例尚未转换为 MvvmCross 5.x(我将尽快开始这样做),但这应该是微不足道的。让我尝试引导您完成它:
- 确保将 MvvmCross iOS 支持包添加到您的 iOS 项目中:
Install-Package MvvmCross.iOS.Support -Version 5.0.2
(或使用图形用户界面)
-
配置您的 iOS 项目以使用MvxSidebarPresenter
通过将以下代码添加到Setup
iOS 项目中的类:
protected override IMvxIosViewPresenter CreatePresenter()
{
return new MvxSidebarPresenter((MvxApplicationDelegate)ApplicationDelegate, Window);
}
-
创建一个充当弹出菜单的视图控制器,并用MvxSidebarPresentationAttribute
。该视图控制器将充当您的菜单。您可以(或者更好应该)将其链接到将处理导航部分(当用户选择菜单项时)的视图模型。这个视图控制器可能看起来像这样:
[MvxSidebarPresentation(MvxPanelEnum.Left, MvxPanelHintType.PushPanel, false)]
public class LeftPanelView : MvxViewController<LeftPanelViewModel>
{
...
}
-
要确保您的主视图充当根控制器,只需添加MvxSidebarPresentationAttribute
到主视图控制器并确保属性Panel
被设定为Center
, HintType
被设定为ResetRoot
and ShowPanel
被设定为true
),像这样:
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true)]
public class HomeView : MvxViewController<HomeViewModel>
{
...
}
-
对于所有子视图(从主视图打开),请确保设置MvxSidebarPresentationAttribute
与财产Panel
set to Center
, HintType
set to PushPanel
并根据是否要在子页面上显示菜单按钮设置ShowPanel
to true
or false
,就像这样:
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.PushPanel, true)]
public class ChildView : MvxViewController<ChildViewModel>
{
...
}
-
最后一步是为菜单中的所有其他按钮设置视图控制器。这些可以简单地用MvxModalPresentationAttribute
属性将它们作为对话框打开(详细文档可以找到here https://www.mvvmcross.com/documentation/platform/ios-view-presenter?scroll=548)。一个例子可能看起来像这样:
[MvxModalPresentation(ModalPresentationStyle = UIModalPresentationStyle.OverFullScreen, ModalTransitionStyle = UIModalTransitionStyle.CrossDissolve)]
public partial class ModalView : MvxViewController<ModalViewModel>
{
...
}
要打开不同的视图,您可以使用 MvvmCross 中的新导航服务。为此,只需允许 MvvmCross IoC 容器将实例注入到视图模型构造函数中(更多详细信息可以在here https://www.mvvmcross.com/documentation/fundamentals/navigation?scroll=62):
public class HomeViewModel : MvxViewModel
{
private readonly IMvxNavigationService _navigationService;
public HomeViewModel(IMvxNavigationService navigationService)
{
_navigationService = navigationService ?? throw new ArgumentNullException(nameof(navigationService));
}
}
EDIT 1:为了能够在菜单按钮上显示图标,您需要实现IMvxSidebarMenu
构成菜单的视图控制器上的界面(参见步骤 3)。通过实现此接口,您可以覆盖菜单的默认行为,示例可以找到here https://github.com/MvvmCross/MvvmCross/blob/develop/TestProjects/iOS-Support/XamarinSidebar/MvvmCross.iOS.Support.Sidebar/Views/BaseMenuViewController.cs(这是演示 MvvmCross 的一部分Xamarin侧边栏 https://github.com/MvvmCross/MvvmCross/tree/develop/TestProjects/iOS-Support/XamarinSidebar应用)。
EDIT 2:我错误地建议您可以在推入导航堆栈的子视图上显示菜单(或其图标)按钮。情况并非如此,压入堆栈的子视图不会显示菜单按钮。在这些情况下ShowPanel
属性被完全忽略。
EDIT 3:有一种方法可以完全实现该模式。我们可以自定义堆栈导航 UI,这样我们就可以模仿 Android 工具栏之类的东西。这种方法是有效的,它基本上要求我们隐藏导航栏并创建具有汉堡菜单、后退按钮和其他按钮的自定义工具栏,并将其放在子视图的上部。以下是关闭和后退按钮所需的代码:
public override void ViewDidLoad()
{
base.ViewDidLoad();
NavigationController.NavigationBarHidden = true;
btnClose.TouchUpInside += (object sender, EventArgs e) =>
{
NavigationController.NavigationBarHidden = false;
NavigationController.PopViewController(false);
};
btnShowMenu.TouchUpInside += (object sender, EventArgs e) =>
{
var sideMenu = Mvx.Resolve<IMvxSidebarViewController>();
sideMenu?.Open(MvxPanelEnum.Left);
};
}