Flutter工程嵌入iOS原生view

280 阅读1分钟

在项目中可能会有在Flutter工程中嵌入原生view的需要,今天就来讲讲这个实现。 打开iOS工程,创建原生view:

//
//  CustomFlutterView.swift
//  Runner
//
//  Created by  on 2021/12/2.
//

import Foundation
import Flutter

class CustomFlutterView: NSObject,FlutterPlatformView {
    
    let label = UILabel()
    var age:Int = 0
        

    init(_ frame: CGRect,viewID: Int64,args :Any?,messenger :FlutterBinaryMessenger) {
            super.init()
            if(args is NSDictionary){
                let dict = args as! NSDictionary
                self.label.text  = dict.value(forKey: "text") as! String
            }else{

            self.label.text = "test-test"
            }

            let methodChannel = FlutterMethodChannel(name: "com.flutter.guide.FlutterView_\(viewID)", binaryMessenger: messenger)
            methodChannel.setMethodCallHandler { (call, result) in
              
                
                let method:String = call.method
                if(method == "getData") {
                    
                    result(["message":"我是原生数据\(self.age)"]);
                    
                        
                }
                
                if (method == "setText") {
            
                    if let dict = call.arguments as? Dictionary<String, Any> {
                        let name:String = dict["name"] as? String ?? ""
                        let age:Int = dict["age"] as? Int ?? -1
                        self.age = age
                        self.label.text = "hello,\(name),年龄:\(age)"
                        
                    }
              
                }
            }
        }
        
        func view() -> UIView {
            return label
        }  
    
}

然后创建FlutterViewFactory,注册view:

//
//  CustomFlutterViewFactory.swift
//  Runner
//
//  Created by  on 2021/12/2.
//

import Foundation
import Flutter

class CustomFlutterViewFactory: NSObject,FlutterPlatformViewFactory{
    
    var messemger:FlutterBinaryMessenger?
    
    override init() {
        super.init()
    }
    
//    required init?(coder: NSCoder) {
//        fatalError("init(coder:) has not been implemented")
//    }
    
   func setBinaryMessage(messemger:FlutterBinaryMessenger) {

    self.messemger = messemger;
        
    }

    func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
        return CustomFlutterView(frame,viewID: viewId,args: args,messenger: self.messemger!) as FlutterPlatformView
       }
       
       func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
           return FlutterStandardMessageCodec.sharedInstance()
       }
   }

AppDelegate中注册FlutterViewFactory:

import UIKit
import Flutter


@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
     GeneratedPluginRegistrant.register(with: self)
    
    let registrar:FlutterPluginRegistrar = self.registrar(forPlugin: "plugins.flutter.io/custom_platform_view_plugin")!
    let factory = CustomFlutterViewFactory.init()
    factory.setBinaryMessage(messemger: registrar.messenger())
    registrar.register(factory, withId: "plugins.flutter.io/custom_platform_view")

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

注意:plugins.flutter.io/custom_platform_view这个字符串要与Flutter中保持一致。 ####嵌入Flutter 在Flutter中调用:

@override
  Widget build(BuildContext context) {

    return  Scaffold(
      body: _buildColumn(),

    );
  }

  Widget _plantformView() {
    if (Platform.isAndroid) {
      return AndroidView(
        viewType: 'plugins.flutter.io/custom_platform_view',
        creationParams: {'text': 'Flutter传给AndroidTextView的参数'},
        onPlatformViewCreated: (viewId) {
          print('viewId:$viewId');
          platforms
              .add(MethodChannel('com.flutter.guide.FlutterView_$viewId'));
        },
        creationParamsCodec: StandardMessageCodec(),
      );
    } else if (Platform.isIOS) {
      return UiKitView(
        viewType: 'plugins.flutter.io/custom_platform_view',
        onPlatformViewCreated: (viewId) {
          print('viewId:$viewId');
          platforms
              .add(MethodChannel('com.flutter.guide.FlutterView_$viewId'));
        },
        creationParams: {'text': 'Flutter传给IOSTextView的参数'},
        creationParamsCodec: StandardMessageCodec(),
      );
    }
  }

  Widget _buildColumn() {
   return Column(
        children: [
          SizedBox(height: 100),
          RaisedButton(
            child: Text('传递参数给原生View'),
            onPressed: () {
              var index = number % 3;
              platforms[index].invokeMethod('setText', {'name': '卢三', 'age': number+1});
              number ++;
            },
          ),
          RaisedButton(
            child: Text('$text'),
            onPressed: () async {
              var index = number % 3;
             var result = await platforms[index].invokeMethod('getData');
              number ++;
             text = '${result['message']}';
             setState(() {

             });

            },
          ),
          Expanded(child: Container(color: Colors.grey, child: _plantformView())),
          Expanded(child: Container(color: Colors.orange, child: _plantformView())),
          Expanded(child: Container(color: Colors.yellow, child: _plantformView())),
        ]
    );
  }
}

效果如图:

2183550-8aa4633be40d0732.webp

Flutter与原生通信下节文章再讲。 代码