You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI无Shell应用iOS18下TabBar悬浮顶部问题求助

修复iOS 18中非Shell MAUI应用TabBar顶部悬浮问题

问题背景

未使用Shell的.NET MAUI应用,升级iOS 18后,原本固定在底部的TabBar变为顶部悬浮样式,针对Shell应用的修复方案不适用。

当前使用的TabbedPage代码

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);
    }
}

已尝试的无效方案

自定义继承TabbedViewHandler的CustomTabbedPageHandler并注册,但未生效。核心问题是错误地将platformView当作UITabBar处理,实际TabbedViewHandler对应的原生控件是UITabBarController而非直接的UITabBar。

相关无效代码:

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;
        }
    }
}

MauiProgram.cs(iOS项目)

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;
    }
}

正确修复方案

修改自定义Handler,获取UITabBarController实例,设置其TabBar的TraitOverrides.HorizontalSizeClass为Unspecified,同时刷新特性确保生效。

步骤1:修改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);
        
        // 获取对应的UITabBarController实例
        if (ViewController is UITabBarController tabBarController)
        {
            // 强制设置TabBar水平尺寸类为未指定,恢复底部布局
            tabBarController.TabBar.TraitOverrides.HorizontalSizeClass = UIUserInterfaceSizeClass.Unspecified;
            // 刷新UI特性使设置生效
            tabBarController.TabBar.SetNeedsUpdateOfUserInterfaceItemProperties();
        }
    }

    protected override void DisconnectHandler(UIView platformView)
    {
        if (ViewController is UITabBarController tabBarController)
        {
            // 清理设置避免内存泄漏
            tabBarController.TabBar.TraitOverrides.HorizontalSizeClass = UIUserInterfaceSizeClass.Regular;
        }
        base.DisconnectHandler(platformView);
    }
}

步骤2:确保Handler注册正确

确认iOS项目的MauiProgram.cs中Handler注册无误(原代码已正确注册,可清理重复引用):

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 =>
        {
            // 注册自定义TabbedPage处理器
            handlers.AddHandler(typeof(TabbedPage), typeof(CustomTabbedPageHandler));
        });

        builder
            .UseSharedMauiApp();

        var app = builder.Build();

        ServiceHelper.ServiceProvider = app.Services;

        return app;
    }
}

额外验证(若仍未生效)

可在CreatePlatformView方法中补充设置:

protected override UIView CreatePlatformView()
{
    var view = base.CreatePlatformView();
    if (ViewController is UITabBarController tabBarController)
    {
        tabBarController.TabBar.TraitOverrides.HorizontalSizeClass = UIUserInterfaceSizeClass.Unspecified;
    }
    return view;
}

内容的提问来源于stack exchange,提问作者CrazyEight

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:17:12