In my AppShell.xaml I have the following code for a TabBar. I can't seem to find a property or anything that allows me to change the font (and font size etc.) of the title.
<TabBar x:Name="TabBar">
<Tab x:Name="HomePage" Title="Home" Icon="tab_home.png">
<ShellContent ContentTemplate="{DataTemplate local:MainPage}" Route="MainPage" />
</Tab>
</TabBar>
Even in Resources/Styles/Styles.xaml I don't see a property in the shell or tabbedpage for font family.
You can try to set Font Icons in Shell Tabs.
Please refer to the following code:
1.add the font you wanted.
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
// add your font here
fonts.AddFont("icomoon.ttf", "FA");
});
return builder.Build();
}
}
2.Usage:
<TabBar>
<ShellContent Title="About" Icon="{FontImage FontFamily=FA , Glyph=}" Route="AboutPage" ContentTemplate="{DataTemplate local:CatsPage}" />
<ShellContent Title="Items" Icon="{FontImage FontFamily=FA , Glyph=}" ContentTemplate="{DataTemplate local:MainPage}" />
</TabBar>
Note:
Please add the font into folder Fonts and make sure the build action is MauiFont.
Based on the answer in how can i remove or hide the text of tabs in TabBar .NET MAUI?
You can change both the font and the font size of the title in the TabBar.
In Android:
You need to add a custom renderer in Platforms/Android/Renderers
[assembly: ExportRenderer(typeof(Shell), typeof(CustomShellRenderer))]
namespace YourApp.Platforms.Android.Renderers;
public class CustomShellRenderer : ShellRenderer
{
public CustomShellRenderer(Context context) : base(context)
{
}
protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
{
return new CustomBottomNavViewAppearanceTracker(this, shellItem);
}
}
public class CustomBottomNavViewAppearanceTracker : ShellBottomNavViewAppearanceTracker
{
public override void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
{
base.SetAppearance(bottomView, appearance);
// Set custom font with any font file name you need as registered in MauiProgram.cs builder.ConfigureFonts()
var font = Typeface.CreateFromAsset(ShellContext.AndroidContext.Assets, "FONTFILENAME.ttf");
// replace FONTSIZE with you needed font size
var spanFace = new CustomTypefaceSpan("", font, FONTSIZE);
// if you need you can change the direction of the bottom navigation view
bottomView.LayoutDirection = LayoutDirection.Rtl;
var menu = bottomView.Menu;
for (var i = 0; i < menu.Size(); i++)
{
// Set custom label with custom fonts
var menuItem = menu.GetItem(i);
if (menuItem == null) continue;
var spannableString = new SpannableString(menuItem.TitleCondensedFormatted);
spannableString.SetSpan(spanFace, 0, spannableString.Length(), SpanTypes.ExclusiveExclusive);
menuItem.SetTitle(spannableString);
}
}
public CustomBottomNavViewAppearanceTracker(IShellContext shellContext, ShellItem shellItem) : base(shellContext, shellItem)
{
ShellContext = shellContext;
}
private IShellContext ShellContext { get; }
}
}
public class CustomTypefaceSpan : TypefaceSpan
{
private float? FontSize { get; }
private readonly Typeface _typeface;
public CustomTypefaceSpan(string family, Typeface typeface, float? fontSize = null) : base(family)
{
FontSize = fontSize;
_typeface = typeface;
}
public override void UpdateDrawState(TextPaint ds)
{
ApplyCustomTypeFace(ds, _typeface);
}
public override void UpdateMeasureState(TextPaint paint)
{
ApplyCustomTypeFace(paint, _typeface);
}
private void ApplyCustomTypeFace(Paint paint, Typeface tf)
{
if (FontSize != null && FontSize != 0)
paint.TextSize = FontSize.Value;
paint.SetTypeface(tf);
}
}
For iOS:
You need to add a custom renderer in Platforms/iOS/Renderers
public class CustomShellRenderer : ShellRenderer
{
protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
{
return new CustomTabBarAppearance(Shell);
}
protected override IShellSectionRenderer CreateShellSectionRenderer(ShellSection shellSection)
{
return new CustomSectionRenderer(this);
}
}
public class CustomSectionRenderer(IShellContext context) : ShellSectionRenderer(context);
public class CustomTabBarAppearance : IShellTabBarAppearanceTracker
{
private Shell Shell { get; }
private CustomTabBar? CustomTabBar => Shell.CurrentItem as CustomTabBar;
public CustomTabBarAppearance(Shell shell)
{
Shell = shell;
}
public void Dispose()
{
}
public void ResetAppearance(UITabBarController controller)
{
}
public void SetAppearance(UITabBarController controller, ShellAppearance appearance)
{
var tabBar = controller.TabBar;
UpdateTabBar(tabBar);
}
[System.Runtime.Versioning.SupportedOSPlatform("ios")]
private void UpdateTabBar(UITabBar? tabBar)
{
if (tabBar == null) return;
var fontFamily = CustomTabBar?.FontFamily;
var fontSize = CustomTabBar?.FontSize ?? 0;
var font = UIFont.FromName(fontFamily, fontSize);
if (OperatingSystem.IsIOSVersionAtLeast(9))
{
tabBar.SemanticContentAttribute =
LangUtilities.IsRtl ?
UISemanticContentAttribute.ForceRightToLeft
: UISemanticContentAttribute.ForceLeftToRight;
}
if (OperatingSystem.IsIOSVersionAtLeast(13)&& UIDevice.CurrentDevice.CheckSystemVersion(13, 0) && DeviceInfo.Platform ==DevicePlatform.iOS)
{
#if IOS13_0_OR_GREATER
void UpdateAppearance(UITabBarItemStateAppearance appearance, bool changeToWhite=true)
{
appearance.TitleTextAttributes = new UIStringAttributes(appearance.TitleTextAttributes.Dictionary)
{
Font = font,
ForegroundColor = Application.Current?.RequestedTheme switch
{
AppTheme.Dark => changeToWhite? UIColor.White:appearance.TitleTextAttributes.ForegroundColor,
_ => appearance.TitleTextAttributes.ForegroundColor
} ?? appearance.TitleTextAttributes.ForegroundColor
};
}
var barAppearance = new UITabBarAppearance(tabBar.StandardAppearance);
var layoutAppearance = barAppearance.StackedLayoutAppearance;
UpdateAppearance( layoutAppearance.Normal);
UpdateAppearance(layoutAppearance.Disabled);
UpdateAppearance(layoutAppearance.Selected,false);
UpdateAppearance(layoutAppearance.Focused);
barAppearance.ShadowColor = null;
barAppearance.ShadowImage = null;
tabBar.StandardAppearance = barAppearance;
#endif
if (OperatingSystem.IsIOSVersionAtLeast(15))
tabBar.ScrollEdgeAppearance = barAppearance;
}
else
{
if (tabBar.Items == null) return;
foreach (var uiTabBarItem in tabBar.Items)
{
var states = new[] { UIControlState.Normal, UIControlState.Selected };
foreach (var state in states)
{
var textAttributes = uiTabBarItem.GetTitleTextAttributes(state);
textAttributes.Font = font;
uiTabBarItem.SetTitleTextAttributes(textAttributes, state);
}
}
}
}
public void UpdateLayout(UITabBarController controller)
{
var tabBar = controller.TabBar;
var height = CustomTabBar?.MinHeight;
if (height != null)
{
if (tabBar.Frame.Height != height)
{
tabBar.Frame = new CGRect(tabBar.Frame.X, tabBar.Frame.Y + (tabBar.Frame.Height - height.Value), tabBar.Frame.Width, height.Value);
}
}
tabBar.ClipsToBounds = false;
}
}
Also create CustomTabBar.cs
public class CustomTabBar : TabBar
{
public CustomTabBar()
{
DescendantAdded += CustomTabBar_DescendantAdded;
}
private void CustomTabBar_DescendantAdded(object? sender, ElementEventArgs e)
{
if (e.Element is ShellContent shellContent)
{
var data = shellContent.ContentTemplate as IDataTemplateController;
shellContent.Route = data.IdString.Split('.').Last().ToLower();
}
}
public static readonly BindableProperty FontSizeProperty = BindableProperty.Create(
nameof(FontSize), typeof(float), typeof(CustomTabBar));
public float FontSize
{
get => (float)GetValue(FontSizeProperty);
set => SetValue(FontSizeProperty, value);
}
public static readonly BindableProperty FontFamilyProperty = BindableProperty.Create(
nameof(FontFamily), typeof(string), typeof(CustomTabBar));
public static readonly BindableProperty MinHeightProperty = BindableProperty.Create(
nameof(MinHeight), typeof(int?), typeof(CustomTabBar));
public int? MinHeight
{
get => (int?)GetValue(MinHeightProperty);
set => SetValue(MinHeightProperty, value);
}
public string FontFamily
{
get => (string)GetValue(FontFamilyProperty);
set => SetValue(FontFamilyProperty, value);
}
}
In MauiProgram.cs add to builder object that call
.ConfigureMauiHandlers(handlers =>
{
#if ANDROID
handlers.AddHandler(typeof(Shell), typeof(Platforms.Android.Renderers.CustomShellRenderer));
#elif IOS
handlers.AddHandler(typeof(Shell), typeof(Platforms.iOS.Renderers.CustomShellRenderer));
#endif
});
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