使用TabbedPage切换iOS NavigationPage.SetHasNavigationBar会导致隐藏选项卡

时间:2015-11-30 12:36:20

标签: c# ios xamarin.forms xamarin-forms

之前有人试过这个场景吗?我正在谈论最新的Xamarin表单2,目标是iOS。

我有一个带有4个标签的TabbedPage,当用户查看前2个时,不应该有导航栏 - 我通过在TabbedPage的构造函数中设置NavigationPage.SetHasNavigationBar(this,false)来实现此功能。 / p>

现在通过使用Xamarin表单实验的ExtendedTabbedPage,我可以连接到名为OnCurrentPageChanged()的更改选项卡事件,在这里我验证我是否在最后两个选项卡之一上并切换NavigationPage.SetHasNavigationBar (这是真的)。​​

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

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

2 个答案:

答案 0 :(得分: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中! / p>

答案 1 :(得分: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,一切正常。