iOS/Flutter混合开发之PlatformView配置与使用
环境:Xcode 16.3、Flutter 3.29.2、Dart 3.7.2。
使用背景:需要在flutter界面中嵌入一个iOS原生控件。
步骤:
1. iOS侧实现:
1.1:PlatformView实现
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.whitearguments = argscreateNativeView(view: _view)}func view() -> UIView {_view}func createNativeView(view _view: UIView) {let testView = UIView() // 创建需要嵌入的视图constrain(testView) { testView intestView.edges == testView.superview!.edges}}
}
1.2:FlutterPlatformViewFactory实现
public class FLNativeViewFactory: NSObject, FlutterPlatformViewFactory {private var messenger: FlutterBinaryMessengerpublic init(messenger: FlutterBinaryMessenger) {self.messenger = messengersuper.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实现
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的控制器)中执行注册方法:
func registrarPlugin() {if !hasPlugin("NativeWebViewPlugin") {let registry = registrar(forPlugin: "NativeWebViewPlugin")registry?.register(FLNativeViewFactory(messenger: binaryMessenger),withId: NativeWebViewPlugin.viewId)}}
2. flutter侧实现
UiKitView(viewType: "platform-view-test",layoutDirection: TextDirection.ltr,creationParams: {'key': 'test'},creationParamsCodec: const StandardMessageCodec(),
);