NPadrutt
NPadrutt

Reputation: 4287

AppShell Tabbar icons do not change color on iOS

I have a .net maui application with AppShell that defines a tabbar with this code:

<TabBar>
    <Tab Title="{x:Static resources:Strings.HomeTitle}">
        <Tab.Icon>
            <FontImageSource FontFamily="MaterialIconsRound" Glyph="home" />
        </Tab.Icon>
        <ShellContent>
            <dashboard:DashboardPage />
        </ShellContent>
    </Tab>

    <Tab Title="{x:Static resources:Strings.StatisticsTitle}">
        <Tab.Icon>
            <FontImageSource FontFamily="MaterialIconsRound" Glyph="donut_small" />
        </Tab.Icon>
        <ShellContent Title="{x:Static resources:Strings.StatisticsTitle}">
            <statistics:StatisticSelectorPage />
        </ShellContent>
    </Tab>

    <Tab Title="{x:Static resources:Strings.MoreTitle}">
        <Tab.Icon>
            <FontImageSource FontFamily="MaterialIconsRound" Glyph="more_horiz" />
        </Tab.Icon>
        <ShellContent>
            <overflowMenu:OverflowMenuPage />
        </ShellContent>
    </Tab>
</TabBar>

On Android the icons do change correctly the color depending on the device theme or when they are selected. On iOS only the text changes. enter image description here enter image description here

Is that a bug or do I have to set a specific style for that?

Upvotes: 3

Views: 1470

Answers (3)

Softlion
Softlion

Reputation: 12615

This is my workaround. Having the issue on both iOs and Android though.

public class TabbedPage2 : TabbedPage
{
    protected override void OnPagesChanged(NotifyCollectionChangedEventArgs e)
    {
        base.OnPagesChanged(e);
        
        
        if (e is { Action: NotifyCollectionChangedAction.Add, NewItems: not null })
        {
            foreach (var page in e.NewItems.OfType<Page>())
                FixIconColor(page);
        }
    }

    /// <summary>
    /// Workaround for  https://github.com/dotnet/maui/issues/8244
    /// </summary>
    private void FixIconColor(Page page)
    {
        if(page.IconImageSource is SvgImageSource imageSource)
        {
            imageSource.ColorMapping = [
                new() { OldColor = Colors.Black, NewColor = UnselectedTabColor},
                new() { OldColor = Colors.White, NewColor = UnselectedTabColor},
            ];
            page.IconImageSource = null;
            page.IconImageSource = imageSource;

            var selectedImageSource = new SvgImageSource
            {
                Source = imageSource.Source,
                Height = imageSource.Height,
                ColorMapping = [new() { OldColor = Colors.Black, NewColor = SelectedTabColor }],
            };
            
            var selectedPageStyle = new Style(typeof(Page)) { ApplyToDerivedTypes = true };
            selectedPageStyle.Triggers.Add(new DataTrigger(typeof(Page))
            {
                Binding = new Binding(nameof(CurrentPage), source: this),
                Value = page,
                Setters = {{ IconImageSourceProperty, selectedImageSource }}
            });
            page.Style = selectedPageStyle;
        }
    }
}

Upvotes: 0

Edward Brey
Edward Brey

Reputation: 41718

This workaround uses triggers to replace the current tab’s icon with an icon that uses the correct color. It assumes you are using a FontImageSource and have a property named App.PrimaryColor that specifies the app’s primary color.

public class FontImageTabbedPage : TabbedPage {
#if IOS
    protected override void OnParentChanged() {
        base.OnParentChanged();

        foreach (var page in Children) {
            var imageSource = (FontImageSource)page.IconImageSource;
            page.Style = new Style(typeof(Page)) {
                ApplyToDerivedTypes = true,
                Triggers = { new DataTrigger(typeof(Page)) {
                    Binding = new Binding(nameof(CurrentPage), source: this),
                    Value = page,
                    Setters = { { IconImageSourceProperty, new FontImageSource {
                        FontFamily = imageSource.FontFamily,
                        Glyph = imageSource.Glyph,
                        Size = imageSource.Size,
                        Color = App.PrimaryColor } } } } },
            };
        }
    }
#endif
}

The starting point for this workaround was a similar one designed for SVG icons.

Upvotes: 0

Jessie Zhang -MSFT
Jessie Zhang -MSFT

Reputation: 13879

There is a known issue about this problem. And this issue has been moved to the Backlog milestone.

You can follow it up here: https://github.com/dotnet/maui/issues/8244 .

Thanks for your support and feedback for maui.

Upvotes: 3

Related Questions