React Native与iOS原生交互(纯干货)

iOS发送消息给RN

iOS中代码
新建RNTEventManager类继承自RCTEventEmitter实现RCTBridgeModule协议

RNTEventManager.h

#import 
#import 
NS_ASSUME_NONNULL_BEGIN

@interface RNTEventManager : RCTEventEmitter
- (void)sendSelectItem:(NSDictionary *)obj;
@end

NS_ASSUME_NONNULL_END

RNTEventManager.m
添加宏RCT_EXPORT_MODULE();
声明支持的事件名字- (NSArray *)supportedEvents
发送消息[self sendEventWithName:@"selectItem" body:obj];
很多人按照官网的到这里就结束了。但是调用后发现会报错,因为需要加上一句话。
单例并且重写allocWithZone

+(id)allocWithZone:(NSZone *)zone {
  static RNTEventManager *sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [super allocWithZone:zone];
  });
  return sharedInstance;
}

完整代码

#import "RNTEventManager.h"

@implementation RNTEventManager
RCT_EXPORT_MODULE();
- (NSArray *)supportedEvents
{
  return @[@"selectItem"];
}

- (void)sendSelectItem:(NSDictionary *)obj
{
  [self sendEventWithName:@"selectItem" body:obj];
}

//.m文件
+(id)allocWithZone:(NSZone *)zone {
  static RNTEventManager *sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [super allocWithZone:zone];
  });
  return sharedInstance;
}
@end

RN中Home.js中
引入NativeEventEmitter NativeModules
NativeModules重命名RNTEventManager
新建calendarManagerEmitter
添加监听calendarManagerEmitter.addListener

完整代码

import { View, Text, StyleSheet, Image, FlatList, Modal, NativeEventEmitter, NativeModules } from 'react-native';
const { RNTEventManager } = NativeModules;
const calendarManagerEmitter = new NativeEventEmitter(RNTEventManager);
const subscription = calendarManagerEmitter.addListener(
    'selectItem',
    (reminder) => {
        console.log(reminder)
    }
);
class Home extends Component{
  ...
}

还有在必要时销毁监听

componentWillUnmount() {
        subscription.remove()
    }

RN使用iOS原生组件

iOS
在iOS中新建一个RNTSwitchView继承自RCTViewManager
RNTSwitchView.h

#import 

NS_ASSUME_NONNULL_BEGIN

@interface RNTSwitchView : RCTViewManager
{
  BOOL _clickItemEvent;
}
@property (nonatomic, copy) RCTBubblingEventBlock selectItem;

@end

NS_ASSUME_NONNULL_END

在.m中注册这个类RCT_EXPORT_MODULE(RNTSwitch)名字为RNTSwitch
-(UIView*)view方法中返回需要的内容

注意: 请不要在-view中给UIView实例设置frame或是backgroundColor属性。为了和 JavaScript 端的布局属性一致,React Native 会覆盖你所设置的值。 如果您需要这种粒度的操作的话,比较好的方法是用另一个UIView来封装你想操作的UIView实例,并返回外层的UIView

RNTSwitchView.m

#import "RNTSwitchView.h"
#import "HZCycleScrollView.h"
#import "RNTEventManager.h"
@implementation RNTSwitchView

RCT_EXPORT_MODULE(RNTSwitch)
RCT_EXPORT_VIEW_PROPERTY(selectItem, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(urlArray, NSArray *)
-(UIView*)view{
  
  HZCycleScrollView* scrollView = [[HZCycleScrollView alloc] init];
  scrollView.cycleScrollViewStyle = HZCycleScrollViewStyleLoop;
  scrollView.selectItemBlock = ^(NSInteger index) {
    RNTEventManager *event = [[RNTEventManager alloc] init];
    [event sendSelectItem:@{@"index":[NSNumber numberWithUnsignedInteger:index]}];

  };
  return scrollView;
}


@end

还有一些用法尚未用到,有时间会整理过来。
完整demo地址(其中还有React Navigation4.x、IconFont、图片查看器react-native-image-zoom-viewer用法具体见上文)

你可能感兴趣的:(React Native与iOS原生交互(纯干货))