简体   繁体   English

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

[英]Show “Back to Menu” Button in iOS NavigationBar with Xamarin.Forms

I'm trying to build a cross-platform app using C# and Xamarin.Forms. 我正在尝试使用C#和Xamarin.Forms构建一个跨平台的应用程序。 It contains a slide-out menu implemented in form of a MasterDetailPage . 它包含以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. 在Android上,左上角有一个带有应用程序图标的按钮,可以切换滑出页面,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: 我将其分解为以下从Xamarin解决方案模板“Blank App(Xamarin.Forms Shared)”派生的最小示例,并替换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 . 可以在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. 我的想法是在iOS特定的代码中添加这样一个“菜单”或“后退”按钮,修改AppDelegate类中的window.RootViewController.NavigationController.NavigationBar But window.RootViewController.NavigationController is null . 但是window.RootViewController.NavigationControllernull

Replacing the return type of GetMainPage() by NavigationPage instead of Page does not help. NavigationPage而不是Page替换GetMainPage()的返回类型没有帮助。

I could add toolbar items via MDPage.ToolbarItems.Add(...) , but they appear in the top right corner. 我可以通过添加工具栏项目MDPage.ToolbarItems.Add(...)但它们出现在右上角

TL;DR TL; DR

Essentially, your Detail page needs to be wrapped in a NavigationPage for the back button to appear in iOS. 基本上,您的Detail页面需要包含在NavigationPage ,以便后退按钮显示在iOS中。


Here's an example of how I structure my apps. 这是我如何构建我的应用程序的示例。

App.cs App.cs

    public static INavigation Navigation { get; set; }

    public static Page GetMainPage(IContainer container)
    {
        return new MainPage();
    }

MainPage.cs 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. 既然你已经完成了这个,你的导航抽屉将按预期运行,你的ActionBar也会如此。

When you want to navigate throughout the app, you use the statically defined Navigation 如果要在整个应用程序中导航,请使用静态定义的Navigation

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

Your on the right track, your NavigatePage needs to go on the Detail so 您在正确的轨道上,您的NavigatePage需要继续详细信息

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

I finally found a solution. 我终于找到了解决方案。 The code basically needs two minor corrections: 代码基本上需要两个小的修正:

  1. Wrap all DetailPage s in a NavigationPage , but not the MasterDetailPage (see #1, #2 and #3 below). 将所有DetailPage包装在NavigationPage ,但不包含MasterDetailPage (请参阅下面的#1,#2和#3)。
  2. Add an Icon to the MasterPage when on iOS (see #4 below). 在iOS上时,在MasterPage添加一个Icon (参见下面的#4)。 Don't forget to a the actual PNG(!) to the iOS resources. 不要忘记实际的PNG(!)到iOS资源。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM