2

以前有人尝试过这种情况吗?我说的是针对 iOS 的最新 Xamarin 表单 2。

我有一个带有 4 个选项卡的 TabbedPage,当用户查看前 2 个选项卡时,不应该有导航栏 - 我通过在 TabbedPage 的构造函数中设置 NavigationPage.SetHasNavigationBar(this, false) 来实现这一点。

现在通过使用 Xamarin 表单实验室的 ExtendedTabbedPage,我可以连接到名为 OnCurrentPageChanged() 的更改选项卡事件,并在此处验证我是否位于最后 2 个选项卡之一并切换 NavigationPage.SetHasNavigationBar(this, true) .

这实际上效果很好,除了 1 个小细节。当导航栏显示时,标签页向下移动,并隐藏底部的标签,因此用户此时无法切换标签。

当我在 tabbedpage 的构造函数中设置 NavigationPage.SetHasNavigationBar(this, true) 并将其保留给所有选项卡时,结果还可以。这意味着我会在每个选项卡上看到一个导航标题和选项卡。

4

2 回答 2

1

好的,我自己找到了解决方案。

所以原来的设置如下,在 App.xaml.cs 我通过下面的代码启动了导航

NavigationPage navigationPage = new NavigationPage(new MainPage());

MainPage 是一个包含多个子项的 TabbedPage。我所做的是在从一个子页面切换到另一个子页面时切换该 MainPage 的 NavigationBar

NavigationPage.SetHasNavigationBar(this, false);
NavigationPage.SetHasNavigationBar(this, true);

但这导致子页面没有被调整大小,当导航栏可见时,页面底部的标签栏不可见。

所以实际的解决方案是不将 MainPage 设置为 NavigationPage,而是将每个子项包装在 NavigationPage 中!这样每个孩子都可以拥有自己的 NavigationBar 并保持参考 MainPage 的大小正确。所以添加每个孩子会是这样的

this.Children.Add (new NavigationPage (new DiscoverPage ()){ Title = "Discover" });

我花了一段时间才弄清楚这一点,因为我通常会将子项添加到 MainPage 的实际 xaml 中,但是这样您就不能将它们包装在 NavigationPage 中,因此我将 MainPage 本身包装在 NavigationPage 中!

于 2015-12-10T08:54:59.777 回答
0

切换 NavagationBar 可见性时,在 NavigationPage 中计算标签页的正确大小可能是一些错误。为了我需要标签页必须在 NavigationPage 我想出了下一个解决方案:

public class BaseNavigationPage : NavigationPage
{
    public BaseNavigationPage() : base()
    {
        this.BarTextColor = Color.White;
    }

    public BaseNavigationPage(Page page) : base(page)
    {
        this.BarTextColor = Color.White;
    }

    protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        base.OnPropertyChanged(propertyName);
        if (propertyName == nameof(CurrentPage))
        {
            Current = CurrentPage;
        }
    }

    private void CurrentPage_PropertyChanging(object sender, PropertyChangingEventArgs e)
    {
        if (e.PropertyName == NavigationPage.HasNavigationBarProperty.PropertyName && _bounds == Rectangle.Zero)
        {
            _bounds = CurrentPage.Bounds;
        }
    }

    private void Current_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == NavigationPage.HasNavigationBarProperty.PropertyName)
        {
            var has = NavigationPage.GetHasNavigationBar(CurrentPage);
            if (has)
            {
                CurrentPage.Layout(_bounds);
                _bounds = Rectangle.Zero;
            }
            else
            {
                CurrentPage.Layout(this.Bounds);
            }
        }
    }

    private Page Current
    {
        get { return _current; }
        set
        {
            if (_current != null)
            {
                _current.PropertyChanging -= CurrentPage_PropertyChanging;
                _current.PropertyChanged -= Current_PropertyChanged;
            }
            _current = value;
            if (_current != null)
            {
                _current.PropertyChanging += CurrentPage_PropertyChanging;
                _current.PropertyChanged += Current_PropertyChanged;
            }
        }
    }

    private Page _current;
    private Rectangle _bounds;
}

并且可以使用 BaseNavigationPage 而不是 NavigationPage 并且一切正常。

于 2017-02-28T18:58:09.173 回答