flutter 调用ios原生控件或第三方控件(swift)

最近做一个ios项目,里面涉及了google地图,flutter也有控件显示google地图,但是这些插件并不能在地图上绘制形状和线条,本人安卓屌丝一枚,不会用oc或者swift开发原生项目,不过我会flutter,swift还和kotlin有点像,想想好像可以应对,就决定用flutter开发界面,然后调用原生的google地图控件

这就开始了 flutter调用第三方(googleMap)控件的历程

另外附上我查看过的,有用的资料(包括Android)

Flutter之在Flutter布局中嵌入原生组件Android篇

创建一个Flutter插件,使用PlatformView显示iOS的本机视图

使用平台通道编写平台特定的代码

第一步:在info.plist里面添加如下代码(这是最重要的一步,所以先说,我上次就是吃了这亏,就差这没写,找了半天的问题)

io.flutter.embedded_views_preview

第二步:写你要调用的控件

要注意的是 你的控件必须继承FlutterPlatformView,请看下面代码,看完后可以照猫画虎

另外 initMethodChannel是给控件注册和原生控件通讯的渠道,和一般Channel通讯没啥区别,flutter官网有讲解的

import Flutter
import Foundation

class GoogleMapView : NSObject,FlutterPlatformView{
    let frame: CGRect;
    let viewId: Int64;
    var messenger: FlutterBinaryMessenger!
    
    init(_ frame: CGRect,viewID: Int64,args :Any?, binaryMessenger: FlutterBinaryMessenger) {
        self.frame = frame;
        self.viewId = viewID;
        self.messenger=binaryMessenger;
    }

    
    func initMethodChannel(){
        let googleMapChannel = FlutterMethodChannel.init(name: "samples.flutter.io/googleMap",
                                                         binaryMessenger: messenger);
        googleMapChannel.setMethodCallHandler({
            (call: FlutterMethodCall, result: FlutterResult) -> Void in
            if(call.method == "startLoaction"){
                //do something
            }else if(call.method == "stopLoaction"){
                
            }
        });
    }
    
    
    func view() -> UIView {
        initMethodChannel()
        var mapView = UILabel()
        mapView.text="阿姨洗吧思密达"
        mapView.color=UIColor.red
        mapView.frame = frame
        return mapView;
    }   
}

第三步:创建FlutterPlatformViewFactory,还请继续照猫画虎,源码我也没看过,不知道为什么

class GoogleMapFactory : NSObject,FlutterPlatformViewFactory{
    
    var messenger: FlutterBinaryMessenger!
    
    func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
        return GoogleMapView(frame,viewID : viewId , args : args,binaryMessenger:messenger);
    }
    
    @objc public init(messenger: (NSObject & FlutterBinaryMessenger)?) {
        super.init()
        self.messenger = messenger
    }
}

第四步:写一个注册控件的类,注册类是要被我们手动调用注册的!!不是系统调用!!所有flutter要调用的控件都要注册的,pluginKey是为了识别该控件有没有被注册过,属于一个标示,和调用 通信没有任何关系,而这个withId就有关系了,这个在调用控件的时候来识别调用的是哪个控件,也就是说这是控件调用的唯一识别码

class GoogleMapViewPlugin {
    static func registerWith(registry:FlutterPluginRegistry) {
        let pluginKey = "Google_MapView_Plugin";
        if (registry.hasPlugin(pluginKey)) {return};
        let registrar = registry.registrar(forPlugin: pluginKey);
        let messenger = registrar.messenger() as! (NSObject & FlutterBinaryMessenger)
        registrar.register(GoogleMapFactory(messenger:messenger),withId: "GoogleMapView");
    }
}

最后一步,注册控件 控件注册是在AppDelegate里面的

override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    //系统自带的
    GeneratedPluginRegistrant.register(with: self)
    //注册我们自己的控件
    GoogleMapViewPlugin.registerWith(registry:  self)

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

现在 ios端的已经没什么要搞的了,下面我们调用下控件试试,看看是不是成功了呢(下面的代码我写的很简略,大家自行补齐哈)

Widget buildMapView(){
    return new Container(
      child: new UiKitView(viewType: "GoogleMapView"),
    );
  }

好了,代码就这么多,有什么问题请在下方留言哈

我的github:https://github.com/OpenFlutter/PullToRefresh;

里面有很多更酷的控件,欢迎Star;如果喜欢Flutter,可以加入我们哦,我们的QQ群是 :892398530

你可能感兴趣的:(Flutter)