美文网首页React Native
RN使用iOS中封装的组件并传值

RN使用iOS中封装的组件并传值

作者: 幽玄727 | 来源:发表于2019-07-25 10:39 被阅读0次

    1.在iOS项目中自定义一个View并在.h方法中暴露一些属性给RN调用

    #import <React/RCTComponent.h>
    
    @class BannerView;
    
    @protocol BannerViewDelegate <NSObject>
    
    -(void)bannerView:(BannerView *)bannerView didSelectItemAtIndex:(NSInteger)index;
    
    
    @end
    
    
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface BannerView : UIView
    
    /** 自动滚动间隔时间,默认2s */
    @property (nonatomic, assign) CGFloat autoScrollTimeInterval;
    
    
    /** 网络图片 url string 数组 */
    @property (nonatomic, strong) NSArray *imageURLStringsGroup;
    
    
    /** 是否自动滚动,默认Yes */
    @property (nonatomic,assign) BOOL autoScroll;
    
    
    @property(nonatomic, weak) id<BannerViewDelegate> delegate;
    //让RN获取其中OC的回调方法
    @property (copy, nonatomic) RCTBubblingEventBlock onBannerClick;
    
    
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    

    在BannerView中,实现其自定义的方法

    #import "BannerView.h"
    #import <SDCycleScrollView.h>
    
    @interface BannerView()<SDCycleScrollViewDelegate>
    
    @property(nonatomic, strong) SDCycleScrollView *adScrollView;
    
    @end
    
    @implementation BannerView
    
    - (instancetype)initWithFrame:(CGRect)frame {
      
      if (self = [super initWithFrame:frame]) {
        
        [self addSubview:self.adScrollView];
        
      }
      return self;
    }
    
    
    -(void)layoutSubviews
    {
      [super layoutSubviews];
      
      self.adScrollView.frame = self.bounds;
    }
    
    
    -(SDCycleScrollView *)adScrollView
    {
      if (!_adScrollView) {
        
        _adScrollView = [[SDCycleScrollView alloc] init];
        _adScrollView.bannerImageViewContentMode = UIViewContentModeScaleAspectFill;
        //设置轮播视图的分页控件的显示
        _adScrollView.showPageControl = YES;
        _adScrollView.autoScroll = YES;
        _adScrollView.delegate = self;
        _adScrollView.placeholderImage = [UIImage imageNamed:@"aa"];
        
      }
      return _adScrollView;
    }
    
    
    -(void)setAutoScrollTimeInterval:(CGFloat)autoScrollTimeInterval
    {
      _autoScrollTimeInterval = autoScrollTimeInterval;
      
      self.adScrollView.autoScrollTimeInterval = autoScrollTimeInterval;
    }
    
    
    -(void)setImageURLStringsGroup:(NSArray *)imageURLStringsGroup
    {
      _imageURLStringsGroup = imageURLStringsGroup;
      
      self.adScrollView.imageURLStringsGroup = imageURLStringsGroup;
    }
    
    -(void)setAutoScroll:(BOOL)autoScroll
    {
      _autoScroll = autoScroll;
      
      self.adScrollView.autoScroll = autoScroll;
    }
    
    
    
    
    #pragma mark  --------------SDCycleScrollViewDelegate-----------
    -(void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index
    {
      
      if ([self.delegate respondsToSelector:@selector(bannerView:didSelectItemAtIndex:)]) {
        
        [self.delegate bannerView:self didSelectItemAtIndex:index];
      }
      
    }
    
    

    2.创建一个管理类和具体实现和RN的交互传值,继承RCTViewManager

    #import <React/RCTViewManager.h>
    #import <React/RCTBridge.h> //导入这个头文件以实现向RN侧发送事件
    #import <React/RCTBridgeModule.h> //导入这个头文件以x实现RCTBridgeModule协议
    #import <React/RCTEventDispatcher.h> //导入这个头文件以实现向RN侧发送事件
    
    #import <React/RCTEventEmitter.h>
    
    #import <SDCycleScrollView.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface BannerScrollerViewManager : RCTViewManager
    
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    其管理类的.m方法中

    #import "BannerScrollerViewManager.h"
    #import "BannerView.h"
    
    @interface BannerScrollerViewManager()<BannerViewDelegate>
    
    @end
    
    @implementation BannerScrollerViewManager
    
    //rct_export_module
    RCT_EXPORT_MODULE(BannerView)
    
    
    -(UIView *)view
    {
      BannerView *view = [[BannerView alloc] init];
      view.delegate = self;
      return view;
      
      
    }
    
    //rct_export_view_property
    RCT_EXPORT_VIEW_PROPERTY(onBannerClick, RCTBubblingEventBlock)
    
    //  通过宏RCT_EXPORT_VIEW_PROPERTY完成属性的映射和导出
    RCT_EXPORT_VIEW_PROPERTY(autoScrollTimeInterval, CGFloat);
    
    RCT_EXPORT_VIEW_PROPERTY(imageURLStringsGroup, NSArray);
    
    RCT_EXPORT_VIEW_PROPERTY(autoScroll, BOOL);
    
    
    
    
    
    -(void)bannerView:(BannerView *)bannerView didSelectItemAtIndex:(NSInteger)index
    {
      
      if (!bannerView.onBannerClick) {
        
        return;
      }
      
      NSString *value = [NSString stringWithFormat:@"点了了哪个=%ld",(long)index];
      
      NSDictionary *params = @{@"value":value};
      
      bannerView.onBannerClick(params);
      
      
      
    }
    
    

    3.在JS方法中,首先单独创建一个js作为该组建的承载器

    import React, {Component} from 'react';
    import {Platform, StyleSheet, Text, View, NativeModules,requireNativeComponent} from 'react-native';
    import PropTypes from 'prop-types';
    
    var BannerView  = requireNativeComponent('BannerView',NativeBannerView);
    
    export default class NativeBannerView extends Component{
    
    
        /**
         *
         * 定义组件需要传到原生端的属性
         * 使用React.PropTypes来进行校验
         */
    
        static propTypes = {
    
            //基础的数据类型
            autoScrollTimeInterval: PropTypes.number,
    
            imageURLStringsGroup: PropTypes.array,
    
            autoScroll: PropTypes.bool,
    
            onSelectImageIndex: PropTypes.func  //方法
        };
    
        /**
         * 默认的值
         *
         */
        static defaultProps = {
    
            autoScrollTimeInterval: '2'
        }
    
    
    
        render(): React.ReactNode {
    
            return <BannerView {...this.props} onBannerClick={(obj) =>{
                this.props.onSelectImageIndex(obj.nativeEvent.value);
            }}/>
        }
    
    }
    
    

    在RN中调用该承载器的时候

         <BannerView style={{height:windowWidth/2,width:windowWidth,marginTop:50}}
                        autoScrollTimeInterval={2}
                        imageURLStringsGroup={['http://photocdn.sohu.com/20111207/Img328215620.jpg',
                          'http://a.hiphotos.baidu.com/lvpics/h=800/sign=2d496375d739b60052ce02b7d9513526/a6efce1b9d16fdfa97d6a678b68f8c5495ee7be9.jpg']}
                        autoScroll={true}
                        onSelectImageIndex={(index) =>{
                            alert(index);
                        }}
                        />
    

    相关文章

      网友评论

        本文标题:RN使用iOS中封装的组件并传值

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