I'm struggling for last few days with TabbedPage
in Xamarin.Forms on iOS. I found some solutions like those:
https://forums.xamarin.com/discussion/20901/hide-tab-bar-on-push
However, none of them works well. I also tried to subclass TabbedRenderer
and set TabBar height to 0. It works, but if I hide TabBar in NavigationPage.Pushed
event handler, there's some delay and for example TableView has blank space on the bottom.
If I try to override NavigationRenderer
and hide/show Tab Bar in PushViewController
/PopViewController
methods it sometimes fails. For example if I navigate fast back and forth, method PopViewController
is not invoked, NavigationStack is broken and Tab Bar is not restored.
I think that the only good solution would be to make this property work: UIViewController.HidesBottomBarWhenPushed
. However, I have no idea how to do it, because setting/overriding it in renderers doesn't work.
Did anybody manage to successfuly show & hide TabBar?
I managed to implement a solution which fixes the issue with blank space after hiding TabBar
. You can read more details about it in this article.
To solve the problem we just need to layout all ChildViewControllers
. Here is my sample implementation of a custom TabbedPage
and its TabbedPageRenderer
.
HideableTabbedPage.cs:
using System;
using Xamarin.Forms;
namespace HideTabBar.Controls
{
public class HideableTabbedPage : TabbedPage
{
public static readonly BindableProperty IsHiddenProperty =
BindableProperty.Create(nameof(IsHidden), typeof(bool), typeof(HideableTabbedPage), false);
public bool IsHidden
{
get { return (bool)GetValue(IsHiddenProperty); }
set { SetValue(IsHiddenProperty, value); }
}
}
}
HideableTabbedPageRenderer.cs:
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using HideTabBar.Controls;
using HideTabBar.iOS.CustomRenderer;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(HideableTabbedPage), typeof(HideableTabbedPageRenderer))]
namespace HideTabBar.iOS.CustomRenderer
{
public class HideableTabbedPageRenderer : TabbedRenderer
{
private bool disposed;
private const int TabBarHeight = 49;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
this.Tabbed.PropertyChanged += Tabbed_PropertyChanged;
}
}
private void Tabbed_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == HideableTabbedPage.IsHiddenProperty.PropertyName)
{
this.OnTabBarHidden((this.Element as HideableTabbedPage).IsHidden);
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
this.disposed = true;
}
private async void OnTabBarHidden(bool isHidden)
{
if (this.disposed || this.Element == null || this.TabBar == null)
{
return;
}
await this.SetTabBarVisibility(isHidden);
}
private async Task SetTabBarVisibility(bool hide)
{
this.TabBar.Opaque = false;
if (hide)
{
this.TabBar.Alpha = 0;
}
this.UpdateFrame(hide);
// Show / Hide TabBar
this.TabBar.Hidden = hide;
this.RestoreFonts();
// Animate appearing
if (!hide)
{
await UIView.AnimateAsync(0.2f, () => this.TabBar.Alpha = 1);
}
this.TabBar.Opaque = true;
this.ResizeViewControllers();
this.RestoreFonts();
}
private void UpdateFrame(bool isHidden)
{
var tabFrame = this.TabBar.Frame;
tabFrame.Height = isHidden ? 0 : TabBarHeight;
this.TabBar.Frame = tabFrame;
}
private void RestoreFonts()
{
// Workaround to restore custom fonts:
foreach (var item in this.TabBar.Items)
{
var text = item.Title;
item.Title = "";
item.Title = text;
}
}
private void ResizeViewControllers()
{
foreach (var child in this.ChildViewControllers)
{
child.View.SetNeedsLayout();
child.View.SetNeedsDisplay();
}
}
}
}
Final result:
There is a solution that doesn't require any renders and works on both Android and iOS.
Wrap the TabbedPage
in a NavigationPage
so the structure of your app becomes
On the TabbedPage you have to hide the navigationbar of the 'root' NavigationPage, otherwise you have 2 navbars.
<TabbedPage
...
HasNavigationBar="False">
If you push a page using the 'root' NavigationPage
, the tabbar is hidden and there is no blank space at the bottom.
See my example at: https://github.com/Jfcobuss/HideTabbarExample/tree/master/HideTabbarExample
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With