Afficher le button "Retour au menu" dans iOS NavigationBar avec Xamarin.Forms

J'essaye de build une application multiplateforme en utilisant C # et Xamarin.Forms. Il contient un drop down menu implémenté sous forme de MasterDetailPage . Sous Android, il y a un button avec l'icône de l'application dans le coin supérieur gauche, ce qui fait basculer la page coulissante, il n'y a pas d'élément de barre de navigation sur iOS.

Je l'ai décomposé en l'exemple minimal suivant dérivé du model de solution Xamarin "Blank App (Xamarin.Forms Shared)" et en remplaçant l'implémentation de la class 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(ssortingng name) { var button = new Button { Text = name }; button.Clicked += delegate { MDPage.Detail = new ContentPage { Content = new Label { Text = name } }; MDPage.IsPresented = false; }; return button; } } 

La solution ainsi que les captures d'écran résultantes peuvent être trouvées sur GitHub .

Mon idée était d'append un tel button "menu" ou "back" dans le code spécifique à iOS en modifiant le window.RootViewController.NavigationController.NavigationBar dans la class AppDelegate . Mais window.RootViewController.NavigationController est null .

Remplacer le type de return de GetMainPage() par NavigationPage au lieu de Page ne aide pas.

Je pourrais append des éléments de barre d'outils via MDPage.ToolbarItems.Add(...) , mais ils apparaissent dans le coin supérieur droit .

    TL; DR

    Essentiellement, votre page de Detail doit être enveloppée dans un NavigationPage pour que le button de return apparaisse dans iOS.


    Voici un exemple de la façon dont je structure mes applications.

    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; } } 

    Maintenant que vous avez fait cela, votre tiroir de navigation se comportera comme prévu, tout comme votre ActionBar.

    Lorsque vous voulez naviguer dans l'application, vous utilisez la Navigation définie statiquement

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

    Votre sur la bonne voie, votre NavigatePage doit aller sur le détail afin

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

    serait

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

    J'ai finalement trouvé une solution. Le code a essentiellement besoin de deux corrections mineures:

    1. Enveloppez tous les DetailPage dans une NavigationPage , mais pas la MasterDetailPage (voir # 1, # 2 et # 3 ci-dessous).
    2. Ajouter une Icon à la MasterPage lorsque sur iOS (voir # 4 ci-dessous). N'oubliez pas le PNG réel (!) Pour les ressources iOS.

    L'exemple de travail minimum est le suivant:

     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(ssortingng 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; } }