.NET MAUI ShellのTabBarでは、以下のようにタブにアイコンを表示することができます。
しかし、iOSでは以下のように大きくアイコンが表示されます。
当記事ではこの解決方法を紹介していきます。
紹介環境
当記事は以下の環境で作成しています。
開発環境
- Visual Studio 2022
- .Net 8
- iOS 17.4
TabBarについて
TabBarは以下のように記載することでタブ表示が行えます。
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="SampleApp.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:SampleApp.Pages"
Shell.FlyoutBehavior="Disabled"
Title="SampleApp">
<TabBar>
<ShellContent Title="サンプル1" ContentTemplate="{DataTemplate pages:SamplePage1}" />
<ShellContent Title="サンプル2" ContentTemplate="{DataTemplate pages:SamplePage2}" />
<ShellContent Title="サンプル3" ContentTemplate="{DataTemplate pages:SamplePage3}" />
</TabBar>
</Shell>
詳細は以下で紹介しています。良ければ参考にしてみてください。
iOSでアイコンが大きくなる現象について
iOSでTabBarのアイコンが大きくなる現象は、アイコンを画像で表示したときに発生します。原因は画像をリサイズさせずに表示するためです。
そのため、画像のサイズを 35×35 にすると以下のようにはみ出さずことなく表示できます。
しかし、この方法ではアイコンがぼやけるため、当記事では別の方法を紹介します。
解決方法について
画像をそのまま表示されていることが問題なため、画像をリサイズできるようにして解決していきます。
手順1:ファイルを準備します
以下のようにファイルを準備します。
手順2:ハンドラーをカスタムします
Shellのハンドラーをカスタムしていきます。
ShellRendererクラスをカスタムします
ShellのiOSのハンドラーはShellRendererクラスになります。そのShellRendererクラスをカスタムするために継承していきます。実装した内容は以下のようになります。
using Microsoft.Maui.Controls.Handlers.Compatibility;
using Microsoft.Maui.Controls.Platform.Compatibility;
namespace SampleApp.Platforms.iOS.Renderers;
// 名前空間はプロジェクトに合わせてください。
public class SampleShellRenderer : ShellRenderer
{
protected override IShellSectionRenderer CreateShellSectionRenderer(ShellSection shellSection)
{
return new SampleShellSectionRenderer(this);
}
}
ShellContentをカスタムするためにCreateShellSectionRendererメソッドを利用していきます。
ShellSectionRendererクラスをカスタムします
CreateShellSectionRendererメソッドで返却しているSampleShellSectionRendererクラスを作成していきます。
ShellContentをカスタムするためにShellSectionRendererクラスを継承します。実装した内容は以下のようになります。
using Microsoft.Maui.Controls.Platform.Compatibility;
using UIKit;
// 名前空間はプロジェクトに合わせてください。
namespace SampleApp.Platforms.iOS.Renderers;
public class SampleShellSectionRenderer : ShellSectionRenderer
{
public SampleShellSectionRenderer(IShellContext context) : base(context)
{
}
protected override void UpdateTabBarItem()
{
base.UpdateTabBarItem();
if (TabBarItem.Image is not null)
TabBarItem.ImageInsets = new UIEdgeInsets(35, 0, 35, 0);
}
}
17行目の「new UIEdgeInsets(35, 0, 35, 0);」でアイコンのサイズを制御しています。例えば、「new UIEdgeInsets(45, 0, 45, 0);」にするとアイコンのサイズは小さくなります。
表示イメージは、以下のようになります。
手順3:カスタムしたハンドラーを登録します
カスタムしたハンドラー(SampleShellRenderer)を登録するために、MauiProgramクラスに以下のように実装していきます。
using Microsoft.Extensions.Logging;
#if IOS
using SampleApp.Platforms.iOS.Renderers;
#endif
namespace SampleApp;
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");
})
/* 追加します。======== */
.ConfigureMauiHandlers((handlers) =>
{
#if IOS
handlers.AddHandler<Shell, SampleShellRenderer>();
#endif
});
/* ==================== */
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
動作イメージ
動作イメージは以下のようになります。
他の解決方法について
他の解決方法としてプロジェクトのプロパティを利用する方法があります。以下で紹介していますので参考にしてみてください。
おわりに
モバイルアプリでタブページはよく利用するので、今回の現象はとても困りました。Xamarinではアセットカタログで解決できましたが、.Net MAUIでは存在していなかったのでカスタムレンダラで解決してみました。当記事が役に立つと幸いです。