How to Increase Font Size for TabBar Menu Items in .NET MAUI on iOS?

202 Views Asked by At

I'm using .NET MAUI Shell Tabbar, and I'm trying to increase the font size of TabBar menu items specifically on the iOS platform.could you provide an example code snippet for this?

I appreciate any suggestions or example code that can help me solve this issue.

1

There are 1 best solutions below

2
Liqun Shen-MSFT On BEST ANSWER

For iOS, as there is no direct api for us to change the font size. We have to totally rewrite the code for our tabbar appearance. So let's override SetAppearance method.

First, in Platform/iOS, create a CustomShellHandler.cs, (Don't worry. Most of the code are from SafeShellTabBarAppearanceTracker)

class CustomShellHandler : ShellRenderer
{
    protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
    {
        return new CustomShellTabBarAppearanceTracker();
    }
}

class CustomShellTabBarAppearanceTracker : ShellTabBarAppearanceTracker
{
    UIColor _defaultBarTint;
    UIColor _defaultTint;
    UIColor _defaultUnselectedTint;
    UITabBarAppearance _tabBarAppearance;
    public override void SetAppearance(UITabBarController controller, ShellAppearance appearance)
    {
        
        IShellAppearanceElement appearanceElement = appearance;
        var backgroundColor = appearanceElement.EffectiveTabBarBackgroundColor;
        var foregroundColor = appearanceElement.EffectiveTabBarForegroundColor; // Currently unused
        var disabledColor = appearanceElement.EffectiveTabBarDisabledColor; // Unused on iOS
        var unselectedColor = appearanceElement.EffectiveTabBarUnselectedColor;
        var titleColor = appearanceElement.EffectiveTabBarTitleColor;

        var tabBar = controller.TabBar;

        if (_defaultTint == null)
        {
            _defaultBarTint = tabBar.BarTintColor;
            _defaultTint = tabBar.TintColor;
            _defaultUnselectedTint = tabBar.UnselectedItemTintColor;
        }
        
        if (OperatingSystem.IsIOSVersionAtLeast(15) || OperatingSystem.IsTvOSVersionAtLeast(15))
            UpdateiOS15TabBarAppearance(controller, appearance);
        else
            UpdateTabBarAppearance(controller, appearance);
        
    }


    void UpdateiOS15TabBarAppearance(UITabBarController controller, ShellAppearance appearance)
    {
        IShellAppearanceElement appearanceElement = appearance;

        var backgroundColor = appearanceElement.EffectiveTabBarBackgroundColor;
        var foregroundColor = appearanceElement.EffectiveTabBarForegroundColor;
        var unselectedColor = appearanceElement.EffectiveTabBarUnselectedColor;
        var titleColor = appearanceElement.EffectiveTabBarTitleColor;

        controller.TabBar.UpdateiOS15TabBarAppearance(
                ref _tabBarAppearance,
                null,
                null,
                foregroundColor ?? titleColor,
                unselectedColor,
                backgroundColor,
                titleColor ?? foregroundColor,
                unselectedColor);
    }

    void UpdateTabBarAppearance(UITabBarController controller, ShellAppearance appearance)
    {
        IShellAppearanceElement appearanceElement = appearance;
        var backgroundColor = appearanceElement.EffectiveTabBarBackgroundColor;
        var foregroundColor = appearanceElement.EffectiveTabBarForegroundColor;
        var unselectedColor = appearanceElement.EffectiveTabBarUnselectedColor;
        var titleColor = appearanceElement.EffectiveTabBarTitleColor;

        var tabBar = controller.TabBar;



        if (backgroundColor is not null && backgroundColor.IsNotDefault())
            tabBar.BarTintColor = backgroundColor.ToPlatform();

        if (unselectedColor is not null && unselectedColor.IsNotDefault())
        {
            tabBar.UnselectedItemTintColor = unselectedColor.ToPlatform();
            UITabBarItem.Appearance.SetTitleTextAttributes(new UIStringAttributes { ForegroundColor = unselectedColor.ToPlatform() }, UIControlState.Normal);
        }

        if (titleColor is not null && titleColor.IsNotDefault() ||
            foregroundColor is not null && foregroundColor.IsNotDefault())
        {
            tabBar.TintColor = (foregroundColor ?? titleColor).ToPlatform();
            UITabBarItem.Appearance.SetTitleTextAttributes(new UIStringAttributes { ForegroundColor = (titleColor ?? foregroundColor).ToPlatform() }, UIControlState.Selected);
        }
    }   
}

Second, in Platform/iOS, create a TabbedViewExtensions.cs. It's from maui source code,TabbedViewExtensions, I made a little changes. I add Font = UIFont.SystemFontOfSize(16f) to UIStringAttributes.

internal static class TabbedViewExtensions
{
    [System.Runtime.Versioning.SupportedOSPlatform("ios15.0")]
    [System.Runtime.Versioning.SupportedOSPlatform("tvos15.0")]
    internal static void UpdateiOS15TabBarAppearance(
        this UITabBar tabBar,
        ref UITabBarAppearance _tabBarAppearance,
        UIColor? defaultBarColor,
        UIColor? defaultBarTextColor,
        Color? selectedTabColor,
        Color? unselectedTabColor,
        Color? barBackgroundColor,
        Color? selectedBarTextColor,
        Color? unSelectedBarTextColor)
    {
        if (_tabBarAppearance == null)
        {
            _tabBarAppearance = new UITabBarAppearance();
            _tabBarAppearance.ConfigureWithDefaultBackground();
        }

        var effectiveBarColor = (barBackgroundColor == null) ? defaultBarColor : barBackgroundColor.ToPlatform();
        // Set BarBackgroundColor
        if (effectiveBarColor != null)
        {
            _tabBarAppearance.BackgroundColor = effectiveBarColor;
        }

        // Set BarTextColor

        var effectiveSelectedBarTextColor = (selectedBarTextColor == null) ? defaultBarTextColor : selectedBarTextColor.ToPlatform();
        var effectiveUnselectedBarTextColor = (unSelectedBarTextColor == null) ? defaultBarTextColor : unSelectedBarTextColor.ToPlatform();

        // Update colors for all variations of the appearance to also make it work for iPads, etc. which use different layouts for the tabbar
        // Also, set ParagraphStyle explicitly. This seems to be an iOS bug. If we don't do this, tab titles will be truncat...

        // Set SelectedTabColor
        if (selectedTabColor is not null)
        {
            var foregroundColor = selectedTabColor.ToPlatform();
            var titleColor = effectiveSelectedBarTextColor ?? foregroundColor;

            _tabBarAppearance.StackedLayoutAppearance.Selected.TitleTextAttributes = new UIStringAttributes { Font=UIFont.SystemFontOfSize(16f),ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.StackedLayoutAppearance.Selected.IconColor = foregroundColor;

            _tabBarAppearance.InlineLayoutAppearance.Selected.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.InlineLayoutAppearance.Selected.IconColor = foregroundColor;

            _tabBarAppearance.CompactInlineLayoutAppearance.Selected.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.CompactInlineLayoutAppearance.Selected.IconColor = foregroundColor;
        }
        else
        {
            var foregroundColor = UITabBar.Appearance.TintColor;
            var titleColor = effectiveSelectedBarTextColor ?? foregroundColor;
            _tabBarAppearance.StackedLayoutAppearance.Selected.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.StackedLayoutAppearance.Selected.IconColor = foregroundColor;

            _tabBarAppearance.InlineLayoutAppearance.Selected.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.InlineLayoutAppearance.Selected.IconColor = foregroundColor;

            _tabBarAppearance.CompactInlineLayoutAppearance.Selected.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.CompactInlineLayoutAppearance.Selected.IconColor = foregroundColor;
        }

        // Set UnselectedTabColor
        if (unselectedTabColor is not null)
        {
            var foregroundColor = unselectedTabColor.ToPlatform();
            var titleColor = effectiveUnselectedBarTextColor ?? foregroundColor;
            _tabBarAppearance.StackedLayoutAppearance.Normal.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.StackedLayoutAppearance.Normal.IconColor = foregroundColor;

            _tabBarAppearance.InlineLayoutAppearance.Normal.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.InlineLayoutAppearance.Normal.IconColor = foregroundColor;

            _tabBarAppearance.CompactInlineLayoutAppearance.Normal.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.CompactInlineLayoutAppearance.Normal.IconColor = foregroundColor;
        }
        else
        {
            var foreground = UITabBar.Appearance.TintColor;
            var titleColor = effectiveUnselectedBarTextColor ?? foreground;
            _tabBarAppearance.StackedLayoutAppearance.Normal.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.StackedLayoutAppearance.Normal.IconColor = foreground;

            _tabBarAppearance.InlineLayoutAppearance.Normal.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.InlineLayoutAppearance.Normal.IconColor = foreground;

            _tabBarAppearance.CompactInlineLayoutAppearance.Normal.TitleTextAttributes = new UIStringAttributes { Font = UIFont.SystemFontOfSize(16f), ForegroundColor = titleColor, ParagraphStyle = NSParagraphStyle.Default };
            _tabBarAppearance.CompactInlineLayoutAppearance.Normal.IconColor = foreground;
        }

        // Set the TabBarAppearance
        tabBar.StandardAppearance = tabBar.ScrollEdgeAppearance = _tabBarAppearance;
    }
}

Well that's a lot of code. But that's almost the same with source code, I just make some changes. So just copy it. You can see source code here, TabbedViewExtensions, SafeShellTabBarAppearanceTracker

Finally, don't forget to add Handler in MauiProgram.cs,

    builder.ConfigureMauiHandlers(handlers =>
    {
        handlers.AddHandler<Shell, CustomShellHandler>();
    });

That's the effect after we set systemfontsize:16,

enter image description here

That's the effect before, enter image description here


Lanscape

enter image description here

Portrait

enter image description here

Hope it helps!