I have a .NET MAUI App without Shell.
it usually has the tabbar attached to the bottom of the page.
Since iOS 18 the tabbar is not attached to the bottom anymore and changed to a floating tabbar at the top of the page.
I already found entries on how to fix that when the MAUI App does use shell here. But in my case the App doesn't use shell.
The code of the tabbed page I am using:
BaseAppTabbedPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Application.CustomControls.BaseAppTabbedPage"
xmlns:local="clr-namespace:MyApp.Application.Views"
xmlns:controls="clr-namespace:MyApp.Application.CustomControls"
xmlns:android="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.AndroidSpecific;assembly=Microsoft.Maui.Controls"
xmlns:localization="clr-namespace:MyApp.Application.Resources.Localization"
android:TabbedPage.ToolbarPlacement="Bottom"
android:TabbedPage.IsSwipePagingEnabled="false">
<!-- IsSwipePagingEnabled is explicit disabled due to problems with the pan gesture and filter sliders and also the swipe back gesture -->
<NavigationPage Title="{Static localization:Strings.TAB_BAR_DASHBOARD_TITLE}" IconImageSource="home" x:Name="DashboardTab" />
<NavigationPage Title="{Static localization:Strings.TAB_BAR_FAVORITES_TITLE}" IconImageSource="favorite" x:Name="FavoriteTab" />
<NavigationPage Title="{Static localization:Strings.TAB_BAR_WATCHLIST_TITLE}" IconImageSource="watchlist" x:Name="WatchlistTab" />
<NavigationPage Title="{Static localization:Strings.TAB_BAR_MORE_TITLE}" IconImageSource="burger" x:Name="MoreTab" />
</TabbedPage>
BaseAppTabbedPage.xaml.cs
using MyApp.Application.Services.Navigation;
using MyApp.Application.Views;
namespace MyApp.Application.CustomControls;
public partial class BaseAppTabbedPage : TabbedPage
{
public BaseAppTabbedPage(INavigationService navigationService)
{
InitializeComponent();
navigationService.PushAsync<DashboardPage>(DashboardTab.Navigation);
navigationService.PushAsync<FavoritePage>(FavoriteTab.Navigation);
navigationService.PushAsync<WatchlistPage>(WatchlistTab.Navigation);
navigationService.PushAsync<MorePage>(MoreTab.Navigation);
}
}
I know it must have something to do with setting the TraitOverrides.HorizontalSizeClass
to UIUserInterfaceSizeClass.Unspecified
but the approaches I did had no effect.
I tried to add a CustomTabbedPageHandler
that inherits TabbedViewHandler
and add it to the ConfigureMauiHandlers
in my MauiProgram.cs
but this seems to not have any effect.
So the problem remains the same
CustomTabbedPageHandler.cs
using Microsoft.Maui.Handlers;
using UIKit;
namespace MyApp.Application.iOS.PlatformSpecificHandlers;
public class CustomTabbedPageHandler : TabbedViewHandler
{
protected override void ConnectHandler(UIView platformView)
{
base.ConnectHandler(platformView);
if (platformView is UITabBar tabBar)
{
tabBar.TraitOverrides.HorizontalSizeClass = UIUserInterfaceSizeClass.Unspecified;
}
}
}
MyApp.Application.iOS/MauiProgram.cs
using MyApp.Application.CustomControls;
using Microsoft.Maui.Controls.Handlers.Compatibility;
using MyApp.Application.CustomControls;
using MyApp.Application.iOS.PlatformSpecificHandlers;
using MyApp.Application.Services;
namespace MyApp.Application.iOS;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler(typeof(TabbedPage), typeof(CustomTabbedPageHandler));
});
builder
.UseSharedMauiApp();
var app = builder.Build();
ServiceHelper.ServiceProvider = app.Services;
return app;
}
}
It's not clear about the navigationService
and the static resource you used, so I test with the following:
<NavigationPage Title="Static localization:Strings.TAB_BAR_DASHBOARD_TITLE" x:Name="DashboardTab" >
<x:Arguments>
<local:MainPage></local:MainPage>
</x:Arguments>
</NavigationPage>
But I still cannot reproduce the issue with .NET9 and .NET8. I understand you want to customize the handler or render of the TabbedPage, you could refer to the following code:
#if IOS
public class CustomTabRenderer: TabbedRenderer
{
public CustomTabRenderer()
{
this.TraitOverrides.HorizontalSizeClass = UIKit.UIUserInterfaceSizeClass.Compact;
}
//public override void ViewWillAppear(bool animated)
//{
// base.ViewWillAppear(animated);
// this.TraitOverrides.HorizontalSizeClass = UIKit.UIUserInterfaceSizeClass.Compact;
//}
//public override void ViewDidLoad()
//{
// base.ViewDidLoad();
// this.TraitOverrides.HorizontalSizeClass = UIKit.UIUserInterfaceSizeClass.Compact;
//}
}
#endif
Register the render in MauiProgram
.ConfigureMauiHandlers(handlers =>
{
#if IOS
handlers.AddHandler<BaseAppTabbedPage, CustomTabRenderer>();
#endif
}
And you could refer to .NET MAUI handlers - .NET MAUI | Microsoft Learn