如果对你的思路有丁点的帮助,麻烦帮忙点个👍哟,谢谢!!!!
我们新建一个RN工程 本文以 MyBasicUIDemo 为例
文章目的:封装一个原生的UI 控件,在RN 上使用,
案例实现功能:
1 原生的view上有一个Button,Label,点击按钮的时候让Label显示文字
2 RN 上有一个text组件,如果原生的Laebl有文字,那么显示oc传递的值,
具体实现步骤:
1、打开RN工程下的ios工程,新建一个继承自UIView的类 MyBasicView
注意点: 需要导入 #import <RCTComponent.h>
写上如下代码:
在 .h 中添加我们需要的属性及方法
@interface MyBasicView : UIView
@property (nonatomic, strong) NSString *name; // Label上将来显示的文字
@property (nonatomic, strong) RCTBubblingEventBlock onClickButton; // 封装代码块 - 回调(用来接收oc传递的参数,并显示在text组件上)
@end
在 .m 中实现具体的代码
#import "MyBasicView.h"
@interface MyBasicView ()
@property (nonatomic, weak) UILabel *myLabel;
@property (nonatomic, weak) UIButton *myButton;
@end
@implementation MyBasicView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UILabel *label = [[UILabel alloc] init];
label.backgroundColor = [UIColor orangeColor];
_myLabel = label;
[self addSubview:label];
UIButton *button = [[UIButton alloc] init];
[_myButton sizeToFit];
_myButton = button;
[button setTitle:@"点击我显示文字" forState:UIControlStateNormal];
[button addTarget:self action:@selector(showText) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.myLabel.center = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5);
self.myButton.center = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5 + 20);
}
- (void)showText
{
self.myLabel.text = self.name;
[self.myLabel sizeToFit];
// 执行 block封装的代码 并向RN传递参数(NSDictionary *)
if (self.onClickButton) {
self.onClickButton(@{@"key":@"我是原生传递给RN的文字 - 小小", @"boolKey":@(self.myLabel.text.length)});
}
}
2、创建一个继承自RCTViewManager的管理类 RCTMyBasicViewManager 来管理我们的原生控件 MyBasicView
2.1 在该类的 .m 文件夹下写入宏
RCT_EXPORT_MODULE( )
2.2 实现 - (UIView *)view ( )方法
#import "RCTMyViewManager.h"
#import "MyBasicView.h"
@implementation RCTMyViewManager
RCT_EXPORT_MODULE()
RCT_EXPORT_VIEW_PROPERTY(name, NSString)// 导出参数供RN 使用
RCT_EXPORT_VIEW_PROPERTY(onClickButton, RCTBubblingEventBlock)// 导出参数供RN 使用
- (UIView *)view
{
return [[MyBasicView alloc] init]; // MyBasicView的尺寸位置以及样式由RN来控制
}
@end
3、在RN 中将这个view 加载进来
3.1 新建一个 MyView的js文件(名字随便)
import React, { Component } from 'react';
import { requireNativeComponent } from 'react-native';
let RCTMyView = requireNativeComponent('RCTMyView', MyView);
// 注意 requireNativeComponent 参数1 为OC 文件中的 RCTMyViewManager 去掉Manager ,参数2 为 js中的 MyView,
// 意思是:将 manager管理的view 映射到 我们创建的js组件中,即:将原生view封装在js组件中
export default class MyView extends Component {
render() {
return <RCTMyView {...this.props}/>
}
}
3.2 在index.ios.js中导入我们自定义组件MyView并使用
import MyView from './MyView'
export default class MyBasicUIDemo extends Component { render() {
return (
<View style={styles.container}>
<Text style={{marginTop:20,backgroundColor:'red'}}>
RN的text组件:{this.state.text}
</Text>
<MyView
style={styles.nativeViewStyle}
name='canshu'
// onClickButton 封装代码 - 拿到OC传递过来的值,显示在自己的text组件上
// 取值注意点:必须通过nativeEvent来获取
onClickButton={(e)=>{
if (e.nativeEvent.boolKey){
this.setState({
text:e.nativeEvent.key
})
}else {
this.setState({
text:'原生label的文字消失了'
})
}
}}/>
</View>
);
}}
最后 - 运行项目即可