【问题标题】:Show "Back to Menu" Button in iOS NavigationBar with Xamarin.Forms使用 Xamarin.Forms 在 iOS NavigationBar 中显示“返回菜单”按钮
【发布时间】:2014-09-02 05:16:19
【问题描述】:

我正在尝试使用 C# 和 Xamarin.Forms 构建跨平台应用程序。它包含一个以MasterDetailPage 形式实现的滑出式菜单。在 Android 上,左上角有一个带有应用图标的按钮,用于切换滑出页面,而在 iOS 上则没有这样的导航栏项目。

我将其分解为以下从 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;
    }
}

可以在GitHub找到解决方案以及生成的屏幕截图。

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

将GetMainPage() 的返回类型替换为NavigationPage 而不是Page 没有帮助。

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

【问题讨论】:

    标签: ios xamarin xamarin.forms navigationbar master-detail


    【解决方案1】:

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

    现在您已完成此操作,您的 Navigation Drawer 将按预期运行,您的 ActionBar 也将如此。

    当你想在整个应用中导航时,你可以使用静态定义的Navigation

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

    【讨论】:

    • 好的,在button.Clicked() 上执行PushAsync 会打开一个带有“返回”按钮的新详细信息页面,但是该按钮会链接回上一个详细信息页面,而不是菜单(又名主页面或MainMenu) 符合预期。而且window.RootViewController.NavigationController还是null,所以不能这样修改按钮。
    • 我想要实现的是与this video 类似的行为。
    • 如果您按照我在上面所做的操作,该视频中的内容是默认行为。您的FirstPage 将是带有该图像的页面。请注意,您还必须在 MainMenu(主)页面上设置图标。
    • 抱歉,我无法使用您的方法 (see App.cs at GitHub) 实现所需的行为。 “返回”按钮总是让我回到 "FirstPage" 而不是 MainMenu。
    • 这就是它的设计工作方式,您是要显示导航菜单吗?
    【解决方案2】:

    你在正确的轨道上,你的 NavigatePage 需要继续 Detail 所以

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

    【讨论】:

    • 这听起来很有希望。 (由于 Android 不允许同时在屏幕上显示多个导航页面,因此我也将 return new NavigationPage(MDPage = ...) 替换为 return MDPage。)但现在我在 Android 上看到了一个图标,在 iOS 上看到了 Master 页面的标题。而window.RootViewController.NavigationController 仍然为空,因此我看不到如何分别进一步控制工具栏或后退按钮的外观。
    【解决方案3】:

    我终于找到了解决办法。代码基本上需要两个小修正:

    1. 将所有DetailPages 包装在NavigationPage 中,但不包括MasterDetailPage(请参阅下面的#1、#2 和#3)。
    2. 在 iOS 上时将Icon 添加到MasterPage(参见下面的#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;
        }
    }
    

    【讨论】:

    • 最初我将此解决方案发布为对我的问题的更新。刚才我决定把它变成一个明确的答案。
    • 这个App类和扩展Application类的App类不一样吗?
    • @Krrish:当我找到这个解决方案时(发布问题后不久),这是扩展 Application 类的方法。由于 Xamarin.Forms 更新,这发生了很大变化。请参阅 here 了解更多最新的主从页面示例。
    • 图标是我缺少的关键要素。噗,后退按钮出现了。
    猜你喜欢
    • 2016-07-03
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多