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);
}}
/>