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

iOS 16中TabView嵌套UINavigationController时navigationTitle失效问题

解决iOS16下TabView嵌套自定义UINavigationController时navigationTitle失效的问题

问题原因

iOS16对SwiftUI与UIKit的交互逻辑做了调整,尤其是TabView和导航控制器的层级整合校验更严格。你原代码里用addChild添加HostingController的方式不规范,未将其设为导航控制器的根视图,导致SwiftUI的navigationTitle修饰符无法正确关联到UIKit的导航栏,最终在TabView环境下标题失效。

修复方案

修改自定义导航控制器包装器和HostingController,让SwiftUI的导航标题能自动同步到UIKit导航栏,同时不用传参或切换到NavigationView:

import SwiftUI

@main
struct CustomUIKitNavigationApp: App {
    var body: some Scene {
        WindowGroup {
            TabView {
                NavigationViewControllerRepresentable {
                    VStack {
                        Text("why navigation title is not working anymore on iOS 16 when in TabView?")
                            .navigationTitle("navigation is not appearing")
                    }
                }
            }
        }
    }
}

struct NavigationViewControllerRepresentable<Content: View>: UIViewControllerRepresentable {
    private let content: () -> Content
    
    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content
    }

    func makeUIViewController(context: Context) -> UINavigationController {
        // 将HostingController设为导航控制器的根视图,建立正确层级
        let hostingVC = HostingController(content: AnyView(content()))
        return UINavigationController(rootViewController: hostingVC)
    }

    func updateUIViewController(_ navController: UINavigationController, context: Context) {
        // 视图更新时同步根视图与导航标题
        guard let hostingVC = navController.topViewController as? HostingController else { return }
        hostingVC.rootView = AnyView(content())
        hostingVC.navigationItem.title = hostingVC.navigationTitle
    }
}

class HostingController: UIHostingController<AnyView> {
    // 读取SwiftUI环境中的navigationTitle值
    @Environment(\.navigationTitle) private var navigationTitle
    
    init(content: AnyView) {
        super.init(rootView: content)
    }

    @objc required dynamic init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) not implemented")
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 同步环境标题到UIKit导航栏
        self.navigationItem.title = navigationTitle
    }
}

关键修改点

  • 替换addChild为将HostingController设为导航控制器的rootViewController,构建合规的导航层级
  • 在HostingController中通过@Environment(\.navigationTitle)自动读取SwiftUI设置的标题,同步到UIKit导航栏
  • 在updateUIViewController中处理视图更新时的标题同步,确保动态修改标题也能生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:10:49