如何在Flutter iOS Swift插件中获取UINavigationController
你之前的代码失败,核心原因是Flutter默认的根视图控制器是FlutterViewController,而非直接的UINavigationController,直接强转自然会失败。以下是几种可靠的实现方式:
方法一:通过插件Registrar获取关联的ViewController(推荐)
Flutter插件注册时的FlutterPluginRegistrar可以直接拿到当前插件绑定的FlutterViewController,再从这个VC向上查找导航控制器,这是最稳定的方式。
完整代码示例
import Flutter import UIKit public class SwiftYourPluginPlugin: NSObject, FlutterPlugin { private var registrar: FlutterPluginRegistrar? public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel(name: "your_plugin_channel", binaryMessenger: registrar.messenger()) let instance = SwiftYourPluginPlugin() instance.registrar = registrar // 保存Registrar引用 registrar.addMethodCallDelegate(instance, channel: channel) } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { // 第一步:获取当前绑定的FlutterViewController guard let flutterVC = registrar?.viewController() else { result(FlutterError(code: "-2", message: "无法获取Flutter视图控制器", details: nil)) return } // 第二步:优先获取当前VC的导航控制器 if let navController = flutterVC.navigationController { // 在这里使用navController调用第三方框架 result(nil) return } // 第三步:遍历父视图层级查找导航控制器 var currentVC = flutterVC while let parentVC = currentVC.parent { currentVC = parentVC if let navController = currentVC as? UINavigationController { // 使用找到的导航控制器 result(nil) return } } // 第四步:兜底检查窗口层级的导航控制器(适配iOS 13+多场景) if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, let keyWindow = windowScene.windows.first(where: { $0.isKeyWindow }), let rootVC = keyWindow.rootViewController { if let navController = rootVC as? UINavigationController { result(nil) } else if let navController = rootVC.presentedViewController as? UINavigationController { result(nil) } else { result(FlutterError(code: "-1", message: "未找到可用的UINavigationController", details: nil)) } } else { result(FlutterError(code: "-3", message: "无法获取当前活跃窗口", details: nil)) } } }
关键说明
- 避免直接强转rootViewController:Flutter项目默认不会把
FlutterViewController包裹在UINavigationController中,除非你手动在iOS工程的AppDelegate/SceneDelegate里做了配置。 - iOS 13+适配:不要再用
UIApplication.shared.windows.first获取窗口,改用connectedScenes获取当前活跃的窗口场景,避免多场景下的异常。 - 层级遍历的必要性:如果你的Flutter页面是被其他原生VC present出来的,直接取
navigationController可能为空,此时需要向上遍历父VC层级查找导航栈。
内容的提问来源于stack exchange,提问作者KT AT CBX
相关产品推荐
相关产品推荐

