iOS/Flutter混合开发之PlatformView配置与使用

环境:Xcode 16.3、Flutter 3.29.2、Dart 3.7.2。

使用背景:需要在flutter界面中嵌入一个iOS原生控件。

步骤:

1. iOS侧实现:

1.1:PlatformView实现

Swift 复制代码
class FLNativeView: NSObject, FlutterPlatformView {
    private var _view: UIView

    // flutter侧传入参数
    private var arguments: Any?

    init(
        frame: CGRect,
        viewIdentifier viewId: Int64,
        arguments args: Any?,
        binaryMessenger messenger: FlutterBinaryMessenger?
    ) {
        _view = UIView()
        super.init()
        _view.backgroundColor = UIColor.white
        arguments = args
        createNativeView(view: _view)
    }

    func view() -> UIView {
        _view
    }

    func createNativeView(view _view: UIView) {
        let testView = UIView() // 创建需要嵌入的视图
        constrain(testView) { testView in
            testView.edges == testView.superview!.edges
        }
    }
}

1.2:FlutterPlatformViewFactory实现

Swift 复制代码
public class FLNativeViewFactory: NSObject, FlutterPlatformViewFactory {
    private var messenger: FlutterBinaryMessenger

    public init(messenger: FlutterBinaryMessenger) {
        self.messenger = messenger
        super.init()
    }

    public func create(
        withFrame frame: CGRect,
        viewIdentifier viewId: Int64,
        arguments args: Any?
    ) -> FlutterPlatformView {
        FLNativeView(
            frame: frame,
            viewIdentifier: viewId,
            arguments: args,
            binaryMessenger: messenger
        )
    }

    public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
        FlutterStandardMessageCodec.sharedInstance()  // 用于参数编解码
    }
}

1.3:FlutterPlugin实现

Swift 复制代码
public class NativeWebViewPlugin: NSObject, FlutterPlugin {
    static let viewId = "platform-view-test"

    public static func register(with registrar: FlutterPluginRegistrar) {
        let factory = FLNativeViewFactory(messenger: registrar.messenger())
        registrar.register(factory, withId: NativeWebViewPlugin.viewId) // 唯一标识符
    }
}

1.4:注册FlutterPlugin(可使用引擎注册、或在FlutterViewController中注册,具体方式结合flutter集成方式和使用场景,这里采用后者)

在目标flutter控制器(需要嵌入原生组件、且继承自FlutterViewController的控制器)中执行注册方法:

Swift 复制代码
    func registrarPlugin() {
        if !hasPlugin("NativeWebViewPlugin") {
            let registry = registrar(forPlugin: "NativeWebViewPlugin")
            registry?.register(
                FLNativeViewFactory(messenger: binaryMessenger),
                withId: NativeWebViewPlugin.viewId
            )
        }
    }

2. flutter侧实现

Dart 复制代码
UiKitView(
   viewType: "platform-view-test",
   layoutDirection: TextDirection.ltr,
   creationParams: {'key': 'test'},
   creationParamsCodec: const StandardMessageCodec(),
);
相关推荐
茶底世界之下3 天前
为什么预览、录制、离线导出不能共享同一个背压策略?
ios·swift
2501_916007473 天前
苹果商店iOS应用上架费用全面解析:开发者计划与审核费用计算
android·ios·小程序·https·uni-app·iphone·webview
君赏3 天前
棉宇宙 Flutter 热更新是如何落地的
flutter
2501_916008893 天前
如何实现iOS App代码混淆:SwiftShield使用指南
android·ios·小程序·https·uni-app·iphone·webview
2501_915909063 天前
移动端开发工具链怎么组合比较好,iOS、Android、跨端三套配置方案
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
恋猫de小郭3 天前
AndroidX 新增 Security State ,支持可编程的系统安全状态查询
android·前端·flutter
zihan5183 天前
自己做软件日记9/21 得到了一个良好的文件结构框架
后端·flutter·前端框架·android studio
东坡肘子3 天前
一场关于 SwiftUI 动画的“原生”之争 -- 肘子的 Swift 周报 #154
人工智能·swiftui·swift
2501_916008893 天前
怎么用 Godot 导出 iOS 应用并上架 App Store?签名字段该填什么?
android·ios·小程序·https·uni-app·iphone·webview
2501_915918414 天前
iOS编程用什么软件好?主流工具Xcode、AppCode、CodeRunner与新兴快蝎对比
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程