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

使用UseMauiEmbedding导致iOS端NavigationController为空的问题

在.NET7 Xamarin iOS项目中嵌入MAUI ContentView时NavigationController为空的解决方法

问题背景

将MAUI ContentView嵌入已迁移至.NET7的Xamarin iOS项目时出现以下异常:

  • 注释builder.UseMauiEmbedding代码,项目可正常运行,NavigationController能被正常识别;
  • 取消注释该代码后,启动屏加载时获取NavigationController.Parent时,NavigationController返回Null,触发空引用崩溃;
  • 核心需求是获取MauiContext以打开MAUI ContentView,但添加builder.UseMauiEmbedding后原有导航结构被破坏。

相关代码片段

AppDelegate代码

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    ...
    var builder = MauiApp.CreateBuilder();

    // 添加该行后NavigationController变为null
    builder.UseMauiEmbedding<Microsoft.Maui.Controls.Application>();
    return true;
}
private HomeController HomeController
{
    get
    {
        return (NavigationController.ParentViewController as SlideoutNavigationController).TopView as HomeController;
    }
}

崩溃日志

2023-08-30 15:57:09.129 LIC.MINDAMobile.iOS[15792:11028708] [AppCenterXamarinCrashes] ERROR: +[MSACWrapperLogger MSACWrapperLog:tag:level:]/10 Unhandled Exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---&gt; System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---&gt; System.NullReferenceException: Object reference not set to an instance of an object.
at LIC.MINDAMobile.iOS.MenuController.get_HomeController() in /Users/stall1/Projects/LIC/mobile-minda/LIC.MINDAMobile.iOS/Controllers/MenuController.cs:line 51
at LIC.MINDAMobile.iOS.MenuController.ViewDidLoad() in /Users/stall1/Projects/LIC/mobile-mi

解决方案

1. 延迟导航控制器的获取逻辑

添加builder.UseMauiEmbedding后,MAUI初始化会改变iOS应用的启动流程,导致ViewDidLoad阶段导航控制器还未完成绑定。将依赖NavigationController的逻辑延迟到视图完全显示后执行:

private HomeController _homeController;

public override void ViewDidAppear(bool animated)
{
    base.ViewDidAppear(animated);
    _homeController = (NavigationController.ParentViewController as SlideoutNavigationController).TopView as HomeController;
    // 所有依赖_homeController的业务逻辑移至此处
}

2. 手动初始化并保留MauiContext

在初始化MAUI嵌入时,手动构建并保存MauiContext,避免干扰原有Xamarin导航结构的初始化:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    ...
    var builder = MauiApp.CreateBuilder();
    builder.UseMauiEmbedding<Microsoft.Maui.Controls.Application>();
    var mauiApp = builder.Build();
    // 将MauiContext存储到全局可访问位置(比如App类的静态属性)
    App.MauiContext = new MauiContext(mauiApp.Services, this);
    return true;
}

3. 调整导航结构与MAUI初始化的顺序

确保Xamarin原有导航结构的初始化在MAUI嵌入代码之前完成,保证导航控制器在MAUI启动前已绑定到窗口:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    // 先初始化Xamarin导航结构
    window = new UIWindow(UIScreen.MainScreen.Bounds);
    var slideoutNav = new SlideoutNavigationController();
    var navController = new UINavigationController(new HomeController());
    slideoutNav.TopView = navController;
    window.RootViewController = slideoutNav;
    window.MakeKeyAndVisible();

    // 再初始化MAUI嵌入
    var builder = MauiApp.CreateBuilder();
    builder.UseMauiEmbedding<Microsoft.Maui.Controls.Application>();
    var mauiApp = builder.Build();
    App.MauiContext = new MauiContext(mauiApp.Services, this);

    return true;
}

4. 添加空引用防护逻辑

修改HomeController属性的getter,增加空值检查,避免直接崩溃同时便于调试定位问题:

private HomeController HomeController
{
    get
    {
        if (NavigationController == null)
        {
            Console.WriteLine("NavigationController未初始化");
            return null;
        }
        var slideoutNav = NavigationController.ParentViewController as SlideoutNavigationController;
        if (slideoutNav == null)
        {
            Console.WriteLine("父视图控制器不是SlideoutNavigationController类型");
            return null;
        }
        return slideoutNav.TopView as HomeController;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:05:23