Показать кнопку "Назад в меню" в навигационной панели iOS с помощью Xamarin.Формы

Я пытаюсь создать кросс-платформенное приложение, используя C# и Xamarin.Формы. Он содержит выдвижное меню, реализованное в виде MasterDetailPage. В то время как на Android есть кнопка со значком приложения в левом верхнем углу, которая переключает страницу слайдов, в iOS нет такого элемента панели навигации.

Я разбил его на следующий минимальный пример, полученный из шаблона решения Xamarin " пустое приложение (Xamarin.Forms Shared)" и замена реализации 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;
    }
}

решение, а также полученные скриншоты можно найти в GitHub.

моя идея состояла в том, чтобы добавить такую кнопку" меню "или" назад " в специфичный для iOS код, изменяющий window.RootViewController.NavigationController.NavigationBar внутри AppDelegate класса. Но!--5-- > is null.

замена возвращаемого типа GetMainPage() by NavigationPage вместо Page не помогает.

я мог бы добавить элементы панели инструментов через MDPage.ToolbarItems.Add(...), но они появляются в верхней право углу.

3 ответов


TL; DR

по сути,Detail страница должна быть обернута в NavigationPage для кнопки "назад", чтобы появиться в iOS.


вот пример того, как я структурирую свои приложения.

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

я, наконец, нашел решение. Код в основном нуждается в двух незначительных исправлениях:

  1. объединить все DetailPageС NavigationPage, а не MasterDetailPage (см. #1, #2 и #3 ниже).
  2. добавить Icon до MasterPage когда на iOS (см. #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;
    }
}