使用 TabbedPage 切换 iOS NavigationPage.SetHasNavigationBar 会导致隐藏选项卡
Toggle iOS NavigationPage.SetHasNavigationBar with TabbedPage results in hiding the tabs
有人试过这种情况吗?我说的是针对 iOS.
的最新 Xamarin forms 2
我有一个带有 4 个选项卡的 TabbedPage,当用户查看前 2 个时,不应该有导航栏 - 我通过在TabbedPage.
现在,通过使用 Xamarin 表单实验室的 ExtendedTabbedPage,我可以连接到名为 OnCurrentPageChanged() 的更改选项卡事件,在这里我验证我是否在最后 2 个选项卡之一上并切换 NavigationPage.SetHasNavigationBar(这个,真的)。
除了 1 个小细节外,这实际上效果很好。当导航栏显示时,标签页向下移动,隐藏底部的标签,此时用户无法切换标签。
当我在标签页的构造函数中设置 NavigationPage.SetHasNavigationBar(this, true) 并将其保留给所有标签时,结果是可以的。这意味着我在每个选项卡上都有一个导航标题和可见的选项卡。
好的,我自己找到了解决方案。
原来的设置如下,在App.xaml.cs中我通过以下代码启动了导航
NavigationPage navigationPage = new NavigationPage(new MainPage());
MainPage 是一个包含几个 children 的 TabbedPage。
我所做的是在从一个 child 页面切换到另一个
页面时切换 MainPage 的 NavigationBar
NavigationPage.SetHasNavigationBar(this, false);
NavigationPage.SetHasNavigationBar(this, true);
但这导致 child 页面未调整大小,当导航栏可见时,页面底部的标签栏不可见。
所以实际的解决方案是不将 MainPage 设置为 NavigationPage,而是将每个 child 包装在 NavigationPage 中!
这样,每个 child 都可以拥有自己的 NavigationBar,从而使参考 MainPage 的大小保持正确。
所以添加每个 child 会像这样
this.Children.Add (new NavigationPage (new DiscoverPage ()){ Title = "Discover" });
我花了一些时间才弄清楚这一点,因为我通常会在 MainPage 的实际 xaml 中添加 children,但那样你就不能将它们包装在 NavigationPage 中,因此为什么我将 MainPage 本身包装在 NavigationPage 中!
在切换 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 并且一切正常。
有人试过这种情况吗?我说的是针对 iOS.
的最新 Xamarin forms 2我有一个带有 4 个选项卡的 TabbedPage,当用户查看前 2 个时,不应该有导航栏 - 我通过在TabbedPage.
现在,通过使用 Xamarin 表单实验室的 ExtendedTabbedPage,我可以连接到名为 OnCurrentPageChanged() 的更改选项卡事件,在这里我验证我是否在最后 2 个选项卡之一上并切换 NavigationPage.SetHasNavigationBar(这个,真的)。
除了 1 个小细节外,这实际上效果很好。当导航栏显示时,标签页向下移动,隐藏底部的标签,此时用户无法切换标签。
当我在标签页的构造函数中设置 NavigationPage.SetHasNavigationBar(this, true) 并将其保留给所有标签时,结果是可以的。这意味着我在每个选项卡上都有一个导航标题和可见的选项卡。
好的,我自己找到了解决方案。
原来的设置如下,在App.xaml.cs中我通过以下代码启动了导航
NavigationPage navigationPage = new NavigationPage(new MainPage());
MainPage 是一个包含几个 children 的 TabbedPage。 我所做的是在从一个 child 页面切换到另一个
页面时切换 MainPage 的 NavigationBarNavigationPage.SetHasNavigationBar(this, false);
NavigationPage.SetHasNavigationBar(this, true);
但这导致 child 页面未调整大小,当导航栏可见时,页面底部的标签栏不可见。
所以实际的解决方案是不将 MainPage 设置为 NavigationPage,而是将每个 child 包装在 NavigationPage 中! 这样,每个 child 都可以拥有自己的 NavigationBar,从而使参考 MainPage 的大小保持正确。 所以添加每个 child 会像这样
this.Children.Add (new NavigationPage (new DiscoverPage ()){ Title = "Discover" });
我花了一些时间才弄清楚这一点,因为我通常会在 MainPage 的实际 xaml 中添加 children,但那样你就不能将它们包装在 NavigationPage 中,因此为什么我将 MainPage 本身包装在 NavigationPage 中!
在切换 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 并且一切正常。