在iOS NavigationBar中用Xamarin.Forms显示“返回菜单”button

我正在尝试使用C#和Xamarin.Forms构build一个跨平台的应用程序。 它包含一个以MasterDetailPageforms实现的滑出式菜单。 在Android上,有一个button,左上angular有一个应用程序图标,用于切换滑出页面,iOS上没有这种导航栏项目。

我把它分解成了从Xamarin解决scheme模板“Blank App(Xamarin.Forms Shared)”派生的以下最小例子,并replace了App类的实现:

 public class App { static MasterDetailPage MDPage; public static Page GetMainPage() { return new NavigationPage( MDPage = new MasterDetailPage { Master = new ContentPage { Title = "Master", Content = new StackLayout { Children = { Link("A"), Link("B"), Link("C") } }, }, Detail = new ContentPage { Content = new Label { Text = "A" } }, }); } static Button Link(string name) { var button = new Button { Text = name }; button.Clicked += delegate { MDPage.Detail = new ContentPage { Content = new Label { Text = name } }; MDPage.IsPresented = false; }; return button; } } 

解决scheme以及生成的截图可以在GitHub上find 。

我的想法是添加这样一个“菜单”或“后退”button在iOS特定的代码中修改AppDelegate类中的window.RootViewController.NavigationController.NavigationBar 。 但window.RootViewController.NavigationControllernull

通过NavigationPage而不是PagereplaceGetMainPage()的返回types不会帮助。

我可以通过MDPage.ToolbarItems.Add(...)添加工具栏项,但它们出现在右上angular。

TL; DR

从本质上讲,您的Detail页面需要被封装在一个NavigationPage ,以便后退button出现在iOS中。


这里是我如何构build我的应用程序的一个例子。

App.cs

  public static INavigation Navigation { get; set; } public static Page GetMainPage(IContainer container) { return new MainPage(); } 

MainPage.cs

 public class MainPage : MasterDetailPage { public MainPage() { Title = "Some Title"; var master = new MainMenu(); var detail = new NavigationPage(new FirstPage()); if (App.Navigation == null) { App.Navigation = detail.Navigation; } Master = master; Detail = detail; } } 

现在你已经完成了这个工作,你的导航抽屉会像预期的那样工作,你的ActionBar也是如此。

当你想浏览整个应用程序,你使用静态定义的Navigation

 await App.Navigation.PushAsync(new FooPage()); // or await App.Navigation.PopAsync(); 

你在正确的轨道上,你的NavigatePage需要去细节

 Detail = new ContentPage { Content = new Label { Text = "A" } } and MDPage.Detail = new ContentPage { Content = new Label { Text = name } }; 

将会

 Detail = new NavigationPage(new ContentPage { Content = new Label { Text = "A" } }) and MDPage.Detail = new NavigationPage(new ContentPage { Content = new Label { Text = name } }); 

我终于find了解决办法。 代码基本上需要两个小的更正:

  1. 将所有DetailPageNavigationPage ,但不包含MasterDetailPage (请参见下面的#1,#2和#3)。
  2. 在iOS上添加一个IconMasterPage (参见下面的#4)。 不要忘了实际的PNG(!)到iOS资源。

最小工作范例如下:

 public static class App { static MasterDetailPage MDPage; public static Page GetMainPage() { return MDPage = new MasterDetailPage { // #1 Master = new ContentPage { Title = "Master", Icon = Device.OS == TargetPlatform.iOS ? "menu.png" : null, // #4 Content = new StackLayout { Children = { Link("A"), Link("B"), Link("C") } }, }, Detail = new NavigationPage(new ContentPage { Content = new Label { Text = "A" } }), // #2 }; } static Button Link(string name) { var button = new Button { Text = name }; button.Clicked += delegate { MDPage.Detail = new NavigationPage(new ContentPage { Content = new Label { Text = name } }); // #3 MDPage.IsPresented = false; }; return button; } }