Search code examples
c#iosxamlmaui.net-8.0

Toolbar colored icons are appearing in Shell.ForegroundColor property on iOS - (MAUI)


I have some colored icons which appear fine in Android, however when I deploy the same App on iOS, the icons turn white (which is defined in styles.xaml) in the Toolbar and grayscale ones remain same.

<Setter Property="Shell.ForegroundColor" Value="{OnPlatform WinUI={StaticResource Primary}, Default={StaticResource White}}" />

The regular grayish icons appear fine on iOS, it is just the colored ones causing the issue.

Doesn't iOS support colored icons in Toolbar?

Toolbar with Icons

This is how it looks on Android like a proper icon.

This is how it looks on Android

I don't want to convert my icons in grayscale to appear properly.


Solution

  • For iOS, the default tint color of ToolbarItems is white. If you want to change it, you may use MAUI Handler to change. Here is a workaround,(Inspired by Vladislav Antonyuk's article and @ColeX answer)

    In Platform/iOS folder, create a new file named CustomShellHandler.cs. In this file, we will create a new CustomShellNavBarAppearanceTracker class and customize/clear the tint color for the icon. I clear the tint color in both UpdateLayout and SetAppearance method (for some particular case).

    public class CustomShellHandler : ShellRenderer
    {
        protected override IShellNavBarAppearanceTracker CreateNavBarAppearanceTracker()
        {
            return new CustomShellNavBarAppearanceTracker(this, base.CreateNavBarAppearanceTracker());
        }
    
    }
    
    class CustomShellNavBarAppearanceTracker : IShellNavBarAppearanceTracker
    {
        private readonly IShellContext shellContext;
        private readonly IShellNavBarAppearanceTracker baseTracker;
    
        public CustomShellNavBarAppearanceTracker(IShellContext shellContext, IShellNavBarAppearanceTracker baseTracker)
        {
            this.shellContext = shellContext;
            this.baseTracker = baseTracker;
        }
    
    
        public void Dispose()
        {
            baseTracker.Dispose();
        }
    
        public void ResetAppearance(UINavigationController controller)
        {
            baseTracker.ResetAppearance(controller);
        }
    
        public void SetAppearance(UINavigationController controller, ShellAppearance appearance)
        {
            baseTracker.SetAppearance(controller, appearance);
    
            var icons = controller.TopViewController.NavigationItem.RightBarButtonItems;
            if (icons != null)
            {
                foreach (var icon in icons)
                {
                    if (icon.Image != null)
                    {
                        icon.Image = icon.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
                        icon.TintColor = UIColor.Clear;
                    }
                }
            }   
        }
    
        public void UpdateLayout(UINavigationController controller)
        {
            baseTracker.UpdateLayout(controller);
    
            var icons = controller.TopViewController.NavigationItem.RightBarButtonItems;
            if (icons != null)
            {
                foreach (var icon in icons)
                {
                    if (icon.Image != null)
                    {
                        icon.Image = icon.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
                        icon.TintColor = UIColor.Clear;
                    }
                }
            }   
        }
    
        public void SetHasShadow(UINavigationController controller, bool hasShadow)
        {
            baseTracker.SetHasShadow(controller, hasShadow);
        }
    }
    

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

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

    Here is the result,

    enter image description here