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裏面添加如下代碼(這是最重要的一步,所以先說,我上次就是吃了這虧,就差這沒寫,找了半天的問題)

<key>io.flutter.embedded_views_preview</key>
<true/>

第二步:寫你要調用的控件

要注意的是 你的控件必須繼承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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章