如何将FlutterViewController添加到UIViewController并复用已有引擎
在iOS TabBar标签页中嵌入Flutter视图(复用已有引擎/避免启动页)
核心思路
要解决你的问题,关键是复用AppDelegate中提前初始化的Flutter引擎,避免创建新引擎导致的启动页,同时将Flutter视图嵌入到TabBar对应的ViewController中,有两种实现方式:
方式一:将FlutterView添加到现有UIViewController
适合需要在原生ViewController中混合Flutter视图和其他原生控件的场景。
步骤1:确保AppDelegate中已初始化并预热Flutter引擎
import Flutter import FlutterPluginRegistrant @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var flutterEngine: FlutterEngine! func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 初始化并预热Flutter引擎,避免启动页 flutterEngine = FlutterEngine(name: "pre_warmed_engine") flutterEngine.run() // 注册所有Flutter插件(如果使用了插件) GeneratedPluginRegistrant.register(with: flutterEngine) return true } }
步骤2:在Tab对应的ViewController中嵌入FlutterView
import UIKit import Flutter class FlutterTabVC: UIViewController { private var flutterView: FlutterView! override func viewDidLoad() { super.viewDidLoad() // 获取AppDelegate中已初始化的引擎 guard let appDelegate = UIApplication.shared.delegate as? AppDelegate, let engine = appDelegate.flutterEngine else { fatalError("Flutter引擎未提前初始化") } // 创建关联已有引擎的FlutterView flutterView = FlutterView(frame: view.bounds, engine: engine) flutterView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // 将FlutterView添加到当前VC的视图层级 view.addSubview(flutterView) // 可选:添加其他原生控件(比如导航栏按钮) navigationItem.rightBarButtonItem = UIBarButtonItem(title: "原生按钮", style: .plain, target: self, action: #selector(onNativeButtonTap)) } @objc private func onNativeButtonTap() { // 示例:原生与Flutter通信 guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } appDelegate.flutterEngine.navigationChannel.invokeMethod("native_button_tapped", arguments: nil) } }
方式二:给FlutterViewController指定已有引擎
适合直接用FlutterViewController作为Tab页的场景,无需额外封装原生VC。
实现代码
import UIKit import Flutter class FlutterTabVC: FlutterViewController { override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { // 获取AppDelegate中的已初始化引擎 guard let appDelegate = UIApplication.shared.delegate as? AppDelegate, let engine = appDelegate.flutterEngine else { fatalError("Flutter引擎未提前初始化") } // 使用已有引擎初始化FlutterViewController super.init(engine: engine, nibName: nibNameOrNil, bundle: nibBundleOrNil) } required init?(coder: NSCoder) { guard let appDelegate = UIApplication.shared.delegate as? AppDelegate, let engine = appDelegate.flutterEngine else { fatalError("Flutter引擎未提前初始化") } super.init(engine: engine, coder: coder) } }
关键注意事项
- 必须在AppDelegate中提前初始化并运行Flutter引擎,这样复用引擎时才不会出现启动页
- 如果使用Flutter插件,务必在AppDelegate中调用
GeneratedPluginRegistrant.register(with: flutterEngine),确保复用引擎的VC能正常使用插件 - 如需向Flutter传递初始化参数,可通过MethodChannel或Engine的navigationChannel实现双向通信
内容的提问来源于stack exchange,提问作者mrgnhnt96
相关产品推荐
相关产品推荐

