React Native

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

2019-07-25  本文已影响0人  幽玄727

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);
                    }}
                    />
上一篇下一篇

猜你喜欢

热点阅读