iOS发送消息给RN
iOS中代码
新建RNTEventManager
类继承自RCTEventEmitter
实现RCTBridgeModule
协议
RNTEventManager.h
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
NS_ASSUME_NONNULL_BEGIN
@interface RNTEventManager : RCTEventEmitter<RCTBridgeModule>
- (void)sendSelectItem:(NSDictionary *)obj;
@end
NS_ASSUME_NONNULL_END
RNTEventManager.m
添加宏RCT_EXPORT_MODULE();
声明支持的事件名字- (NSArray<NSString *> *)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<NSString *> *)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 <React/RCTViewManager.h>
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用法具体见上文)
网友评论