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

如何将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:23:05