本篇文章 中写到的是 flutter 通过 UiKitView 调用了ios 原生的 UILabel 案例。
flutter 中嵌套使用ios原生组件的流程基本上可以描述为:
- 1 info.plist文件设置
- 2 ios 端实现原生组件PlatformView提供原生view
- 3 ios 端创建PlatformViewFactory用于生成PlatformView
- 4 ios 端创建FlutterPlugin用于注册原生组件
- 5 flutter 平台嵌入 原生view
1 info.plist文件设置
iOS端的UiKitView目前还只是preview状态, 默认是不支持的, 需要手动打开开关, 在info.plist文件中新增一行io.flutter.embedded_views_preview为true.
如果不添加,会抛出如下异常:
Trying to embed a platform view but the PrerollContext does not support embedding1
![4fc0814c4017925398f898f06fcd2ec6.png](https://i-blog.csdnimg.cn/blog_migrate/29947b6c2ffa8d6f170a674bc8e7b799.jpeg)
2 创建IOS 原生View
创建类 FlutterIosTextLabel 并实现FlutterPlatformView 协议
FlutterIosTextLabel.h
#import #import NS_ASSUME_NONNULL_BEGIN//实现协议FlutterPlatformView@interface FlutterIosTextLabel : NSObject-(instancetype)initWithWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args binaryMessenger:(NSObject*)messenger;@endNS_ASSUME_NONNULL_END
FlutterIosTextLabel.m
#import "FlutterIosTextLabel.h"@implementation FlutterIosTextLabel{ //FlutterIosTextLabel 创建后的标识 int64_t _viewId; UILabel * _uiLabel; //消息回调 FlutterMethodChannel* _channel;}//在这里只是创建了一个UILabel-(instancetype)initWithWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject *)messenger{ if ([super init]) { if (frame.size.width==0) { frame=CGRectMake(frame.origin.x, frame.origin.y, [UIScreen mainScreen].bounds.size.width, 22); } _uiLabel =[[UILabel alloc] initWithFrame:frame]; _uiLabel.textColor=[UIColor redColor]; _uiLabel.text=@"ios 原生 uilabel "; _uiLabel.font=[UIFont systemFontOfSize:14]; _uiLabel.textAlignment=NSTextAlignmentCenter; _uiLabel.backgroundColor=[UIColor grayColor]; _viewId = viewId; } return self; }- (nonnull UIView *)view { return _uiLabel;}@end
2 创建PlatformViewFactory
FlutterIosTextLabelFactory.h
#import #import NS_ASSUME_NONNULL_BEGIN@interface FlutterIosTextLabelFactory : NSObject- (instancetype)initWithMessenger:(NSObject*)messager;@endNS_ASSUME_NONNULL_END
FlutterIosTextLabelFactory.m
#import "FlutterIosTextLabelFactory.h"#import "FlutterIosTextLabel.h"@implementation FlutterIosTextLabelFactory{ NSObject*_messenger;}- (instancetype)initWithMessenger:(NSObject *)messager{ self = [super init]; if (self) { _messenger = messager; } return self;}//设置参数的编码方式 -(NSObject *)createArgsCodec{ return [FlutterStandardMessageCodec sharedInstance];}//用来创建 ios 原生view- (nonnull NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args { //args 为flutter 传过来的参数 FlutterIosTextLabel *textLagel = [[FlutterIosTextLabel alloc] initWithWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger]; return textLagel;}@end
4 创建Plugin
FlutterIosTextLabelPlugin.h
#import #import NS_ASSUME_NONNULL_BEGIN@interface FlutterIosTextLabelPlugin :NSObject@endNS_ASSUME_NONNULL_END
FlutterIosTextLabelPlugin.m
#import "FlutterIosTextLabelPlugin.h"#import "FlutterIosTextLabelFactory.h"@implementation FlutterIosTextLabelPlugin+ (void)registerWithRegistrar:(nonnull NSObject *)registrar { //注册插件 //注册 FlutterIosTextLabelFactory //com.flutter_to_native_test_textview 为flutter 调用此 textLabel 的标识 [registrar registerViewFactory:[[FlutterIosTextLabelFactory alloc] initWithMessenger:registrar.messenger] withId:@"com.flutter_to_native_test_textview"];}@end
然后就是AppDelegate 中注册插件
import UIKitimport Flutter@UIApplicationMain@objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { //flutter 中引用的插件通过些类来注册 GeneratedPluginRegistrant.register(with: self); ... .. //注册插件 FlutterIosTextLabelPlugin.register(with: self); return super.application(application, didFinishLaunchingWithOptions: launchOptions) }}
flutter页面中使用UiKitView嵌入ios 原生UILabel
![3aa91c6ac32d320c16428915429037e5.png](https://i-blog.csdnimg.cn/blog_migrate/01540d9ba8824cea17c8183344356a83.jpeg)
//这里设置的 viewType值与 ios 中插件注册的标识 一至// [registrar registerViewFactory:[[FlutterIosTextLabelFactory alloc] initWithMessenger:registrar.messenger] withId:@"com.flutter_to_native_test_textview"];@override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: appBar, //显示的页面 body: Container( height: 200, child: UiKitView( //设置标识 viewType: "com.flutter_to_native_test_textview", ), ), ); }