FlutterBoost implements Flutter page embedded iOS view

When using Flutter hybrid development, you will encounter some native controls that are better than Flutter. If you don’t want to use Flutter’s controls, you want to use native controls in Flutter. At this time, you will use the native view embedded in the Flutter page. Here is a brief introduction to a view embedded in iOS.

Note: FlutterBoost is used here. Most of the codes on the Internet cannot be executed. In this case, at least it can be used normally.

  • Native part.
    Here we start processing in the native part.
  • Custom viewFlutterIosTextLabel
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>

NS_ASSUME_NONNULL_BEGIN

@interface FlutterIosTextLabel : NSObject<FlutterPlatformView>

@property (nonatomic, strong) UILabel *label;


- (instancetype)initWithFrame:(CGRect)frame
               viewIdentifier:(int64_t)viewId
                    arguments:(id _Nullable)args
              binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;

@end

NS_ASSUME_NONNULL_END
#import "FlutterIosTextLabel.h"

@implementation FlutterIosTextLabel

//在这里只是创建了一个UILabel
- (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
    
    
  if (self = [super init]) {
    
    
      self.label = [UILabel new];
      self.label.backgroundColor = [UIColor yellowColor];
      self.label.textColor = [UIColor redColor];
      self.label.textAlignment = NSTextAlignmentCenter;
      self.label.numberOfLines = 0;
      NSDictionary *dict = (NSDictionary *)args;
      NSString *textValue = dict[@"content"];
      self.label.text = [NSString stringWithFormat:@"我是iOSView \n在显示:%@", textValue];
  }
  return self;
}

- (nonnull UIView *)view {
    
    
    return self.label;
}

@end
  • createFlutterIosTextLabelFactory
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>


NS_ASSUME_NONNULL_BEGIN

@interface FlutterIosTextLabelFactory : NSObject<FlutterPlatformViewFactory>

- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;


@end

NS_ASSUME_NONNULL_END
#import "FlutterIosTextLabelFactory.h"
#import "FlutterIosTextLabel.h"



@implementation FlutterIosTextLabelFactory
{
    
    
    NSObject<FlutterBinaryMessenger> *_messenger;
}

- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
    
    
  self = [super init];
  if (self) {
    
    
    _messenger = messenger;
  }
  return self;
}

- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args {
    
    
  return [[FlutterIosTextLabel alloc] initWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger];
}

-(NSObject<FlutterMessageCodec> *)createArgsCodec{
    
    
    return [FlutterStandardMessageCodec sharedInstance];
}
  • createFlutterIosTextLabelPlugin
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>

NS_ASSUME_NONNULL_BEGIN

@interface FlutterIosTextLabelPlugin : NSObject<FlutterPlugin>
+ (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar> *)registrar;
@end

NS_ASSUME_NONNULL_END
#import "FlutterIosTextLabelPlugin.h"
#import "FlutterIosTextLabelFactory.h"

@implementation FlutterIosTextLabelPlugin

+ (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar> *)registrar {
    
    
    
    //注册插件
    //注册 FlutterIosTextLabelFactory
    //custom_platform_view 为flutter 调用此  textLabel 的标识
    [registrar registerViewFactory:[[FlutterIosTextLabelFactory alloc] initWithMessenger:registrar.messenger] withId:@"custom_platform_view"];
}
@end

At this point, the native integration is half complete, and the focus is on the next part.

Integrated use in AppDelegate
Modification AppDelegate.h: Modify inheritance to FlutterAppDelegate(not required) and delete windowattributes, because FlutterAppDelegateAppDelegate already has its own windowattributes.

The original AppDelegate inheritance relationship does not have to inherit FlutterAppDelegate, as long as it is correctly registered in FlutterBoost.instance.

#import <UIKit/UIKit.h>
#import <Flutter/Flutter.h>

@interface AppDelegate : FlutterAppDelegate
@end

AppDelegate.mIntroduce relevant header files in

#import "FlutterIosTextLabel.h"
#import "GeneratedPluginRegistrant.h"
#import "FlutterIosTextLabelPlugin.h"

Register the plug-in in AppDelegate.m. When introduced flutter_boost, you need to wait for flutter_boost initialization to be completed before FlutterEngineinitializing the plug-in.

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    
    HYFlutterBoostDelegate* delegate = [[HYFlutterBoostDelegate alloc]init];
    
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    
    
    HYTabBarController *tab = [[HYTabBarController alloc]init];

    self.window.rootViewController = tab;
    [self.window makeKeyAndVisible];
    
    
    [FlutterBoost.instance setup:application delegate:delegate callback:^(FlutterEngine *engine) {
    
    
        NSLog(@"FlutterBoost 开始操作");
        // 使用 MethodChannel
        [HYFlutterNavChannel start];
        [HYFlutterCommonChannel start];

        
        // 初始化Flutter内嵌iOSView插件
//        NSObject<FlutterPluginRegistrar> *registrar = [engine registrarForPlugin:@"custom_platform_view_plugin"];
//        FlutterIosTextLabelFactory *factory = [[FlutterIosTextLabelFactory alloc] initWithMessenger:registrar.messenger];
//        [registrar registerViewFactory:factory withId:@"custom_platform_view"];
        
        // `升级处理` 这里正确注册使用即可
        NSObject<FlutterPluginRegistrar> *registrar = [engine registrarForPlugin:@"custom_platform_view_plugin"];
        [FlutterIosTextLabelPlugin registerWithRegistrar:registrar];
        
    }];
    
    return YES;
}


@end

Now that the native integration is complete, let’s integrate it in Flutter.

  • Flutter part
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class CMNativePage extends StatelessWidget {
    
    
  const CMNativePage({
    
    Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      appBar: AppBar(
        title: const Text("详情"),
      ),
      body: const Center(
        child: IOSCompositionWidget(),
      ),
    );
  }
}

class IOSCompositionWidget extends StatelessWidget {
    
    
  const IOSCompositionWidget({
    
    super.key});

  
  Widget build(BuildContext context) {
    
    
    // This is used in the platform side to register the view.
    const String viewType = 'custom_platform_view';
    // Pass parameters to the platform side.
    final Map<String, dynamic> creationParams = {
    
    
      'content': 'Flutter传给原生iOSView的参数'
    };

    return UiKitView(
      viewType: viewType,
      creationParams: creationParams,
      creationParamsCodec: const StandardMessageCodec(),
    );
  }
}

Register route

static const String nativaPage = '/nativaPage';
 nativaPage: (settings, uniqued) {
    
    
      return MaterialPageRoute(
          settings: settings,
          builder: (_) {
    
    
            return const CMNativePage();
          });
    },

Used in Flutter

 TextButton(
            child: const Text("加载原生控件"),
            onPressed: () {
    
    
              BoostNavigator.instance
                  .push(HYRouter.nativaPage, arguments: {
    
    "home": "home页面传递数值"});
              // showBottomWidget(context, const CMNativePage());
            },
          ),

At this point, the integration in Flutter is also completed.
If you want some pop-up styles, handle it yourself. Here we simply use Flutter to embed iOS native views.

Things to note :

  1. FlutterIosTextLabelFactoryThe methods in createArgsCodecmust not be omitted, otherwise the value transfer will be unsuccessful. The type must also be consistent with Dartthe partial native.dart-> IOSCompositionWidget-> UiKitView-> . creationParamsCodecOtherwise it will cause a crash.
  2. There is no problem if you use the writing method in the official documents, but in this case flutter_boost is used, and problems will arise if you integrate it with the official website. The initialization needs to flutter_boostbe completed before FlutterEngineinitializing the plug-in.
  3. Among them withId:xxx, xxx represents the ID of the control, which needs to be consistent with the one IOSCompositionWidgetin the Dart part. viewTypeNamed: custom_platform_view.
  4. Among them registrarForPlugin:xxx, xxx represents the ID of the plug-in. Named: custom_platform_view_plugin.

Native and flutter communicate with each other:

Guess you like

Origin blog.csdn.net/tongwei117/article/details/132321437