美文网首页
React Native与iOS原生交互(纯干货)

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

作者: FateOfKing | 来源:发表于2019-10-14 16:30 被阅读0次

    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用法具体见上文)

    相关文章

      网友评论

          本文标题:React Native与iOS原生交互(纯干货)

          本文链接:https://www.haomeiwen.com/subject/kbbrmctx.html