アイキャッチ画像

【iOS】.NET MAUIのTabbedPageでアイコンが大きくなる問題の解決方法

.NET MAUIのTabbedPageでは、以下のようにタブにアイコンを表示することができます。

Androidの表示イメージ

しかし、iOSでは以下のように大きくアイコンが表示されます。

iOSの表示イメージ

当記事ではこの解決方法を紹介していきます。

紹介環境

当記事は以下の環境で作成しています。

開発環境

  • Visual Studio 2022
  • .Net 8
  • iOS 17.4

TabbedPageについて

TabbedPageは以下のように記載することでタブ表示が行えます。

<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:android="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.AndroidSpecific;assembly=Microsoft.Maui.Controls"
    xmlns:page="clr-namespace:SampleApp.Pages"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    android:TabbedPage.ToolbarPlacement="Bottom"
    x:Class="SampleApp.Pages.SampleTabPage">
    <page:SamplePage1 />
    <page:SamplePage2 />
    <page:SamplePage3 />
</TabbedPage>

詳細は以下で紹介しています。良ければ参考にしてみてください。

iOSでアイコンが大きくなる現象について

iOSでTabbedPageのアイコンが大きくなる現象は、アイコンを画像で表示したときに発生します。原因は画像をリサイズさせずに表示するためです。

そのため、画像のサイズを 35×35 にすると以下のようにはみ出さずことなく表示できます。

画像サイズを35×35にした時のiOSの表示イメージ

しかし、この方法ではアイコンがぼやけるため、当記事では別の方法を紹介します。

解決方法について

画像をそのまま表示されていることが問題なため、画像をリサイズできるようにして解決していきます。

手順1:ファイルの準備します

以下のようにファイル準備します。

準備するファイル

手順2:ハンドラーをカスタムします

iOSのTabbedPageのハンドラーをカスタムするためにTabbedRendererを継承してCustomTabbedRendererクラスを作成していきます。内容は以下のようになります。

using Microsoft.Maui.Controls.Handlers.Compatibility;
using UIKit;

// 名前空間はプロジェクトに合わせてください。
namespace SampleApp.Platforms.iOS.Renderer;

public class CustomTabbedRenderer : TabbedRenderer
{
    public override void AddChildViewController(UIViewController childController)
    {
        base.AddChildViewController(childController);
        if (childController.TabBarItem.Image is null) return;
        // アイコンのサイズを制御しています。
        childController.TabBarItem.ImageInsets = new UIEdgeInsets(35, 0, 35, 0);
    }
}

14行目の「new UIEdgeInsets(35, 0, 35, 0);」でアイコンのサイズを制御しています。例えば、「new UIEdgeInsets(45, 0, 45, 0);」にするとアイコンのサイズは小さくなります。

表示イメージは、以下のようになります。

new UIEdgeInsets(35, 0, 35, 0) の表示イメージ
new UIEdgeInsets(35, 0, 35, 0) の場合
new UIEdgeInsets(45, 0, 45, 0) の表示イメージ
new UIEdgeInsets(45, 0, 45, 0) の場合

手順3:カスタムしたハンドラーを登録します

カスタムしたハンドラー(CustomTabbedRenderer)をを登録するためにMauiProgramクラスに以下の内容を追加していきます。

        builder.ConfigureMauiHandlers(handlers =>
        {
#if IOS
            handlers.AddHandler<TabbedPage, SampleApp.Platforms.iOS.Renderer.CustomTabbedRenderer>();
#endif
        });

追加した例が以下のようになります。

// 名前空間はプロジェクトに合わせてください。
namespace SampleApp;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder.UseMauiApp<App>();

        /* ----- 追加部分 ----- */
        builder.ConfigureMauiHandlers(handlers =>
        {
            // ConfigureMauiHandlersに以下の部分を追加します。
#if IOS
            handlers.AddHandler<TabbedPage, SampleApp.Platforms.iOS.Renderer.CustomTabbedRenderer>();
#endif
        });
        /* ----- 追加部分 ----- */

        return builder.Build();
    }
}

動作イメージ

動作イメージは以下のようになります。

解決後のiOSの動作イメージ

他の解決方法について

他の解決方法としてプロジェクトのプロパティを利用する方法があります。以下で紹介していますので参考にしてみてください。

おわりに

iOSでTabbedPageでアイコンを表示させるとはみ出ていたのでかなり困りました。Xamarinではアセットカタログで解決できましたが、.Net MAUIでは存在していなかったのでカスタムレンダラで解決してみました。当記事が役に立つと幸いです。