iOS发送消息给RN
iOS中代码
新建RNTEventManager类继承自RCTEventEmitter实现RCTBridgeModule协议
RNTEventManager.h
1 2 3 4 5 6 7 8 9
| #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
1 2 3 4 5 6 7 8
| +(id)allocWithZone:(NSZone *)zone { static RNTEventManager *sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [super allocWithZone:zone]; }); return sharedInstance; }
|
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #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
完整代码
1 2 3 4 5 6 7 8 9 10 11 12
| 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{ ... }
|
还有在必要时销毁监听
1 2 3
| componentWillUnmount() { subscription.remove() }
|
RN使用iOS原生组件
iOS
在iOS中新建一个RNTSwitchView继承自RCTViewManager
RNTSwitchView.h
1 2 3 4 5 6 7 8 9 10 11 12 13
| #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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #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用法具体见上文)