问题
I'm trying to build a cross-platform app using C# and Xamarin.Forms. It contains a slide-out menu implemented in form of a MasterDetailPage
. While on Android there is a button with the app icon in the top left corner, which toggles the slide-out page, there is no such navigation bar item on iOS.
I broke it down to the following minimum example derived from the Xamarin solution template "Blank App (Xamarin.Forms Shared)" and replacing the implementation of the App
-class:
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;
}
}
The solution as well as resulting screenshots can be found at GitHub.
My idea was to add such a "menu" or "back" button in the iOS-specific code modifying the window.RootViewController.NavigationController.NavigationBar
within the AppDelegate
class. But window.RootViewController.NavigationController
is null
.
Replacing the return type of GetMainPage()
by NavigationPage
instead of Page
does not help.
I could add toolbar items via MDPage.ToolbarItems.Add(...)
, but they appear in the top right corner.
回答1:
TL;DR
Essentially, your Detail
page needs to be wrapped in a NavigationPage
for the back button to appear in iOS.
Here's an example of how I structure my apps.
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;
}
}
Now that you've done this, your Navigation Drawer will behave as expected, and so will your ActionBar.
When you want to navigate throughout the app, you use the statically defined Navigation
await App.Navigation.PushAsync(new FooPage());
// or
await App.Navigation.PopAsync();
回答2:
Your on the right track, your NavigatePage needs to go on the Detail so
Detail = new ContentPage { Content = new Label { Text = "A" } }
and
MDPage.Detail = new ContentPage { Content = new Label { Text = name } };
would be
Detail = new NavigationPage(new ContentPage { Content = new Label { Text = "A" } })
and
MDPage.Detail = new NavigationPage(new ContentPage { Content = new Label { Text = name } });
回答3:
I finally found a solution. The code basically needs two minor corrections:
- Wrap all
DetailPage
s in aNavigationPage
, but not theMasterDetailPage
(see #1, #2 and #3 below). - Add an
Icon
to theMasterPage
when on iOS (see #4 below). Don't forget to a the actual PNG(!) to the iOS resources.
The minimum working example is as follows:
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;
}
}
来源:https://stackoverflow.com/questions/24700112/show-back-to-menu-button-in-ios-navigationbar-with-xamarin-forms