本文以封装一个 UIButton 给 React Native 使用为例.
- 创建一个继承自 UIbutton 的类
#import <UIKit/UIKit.h>
#import <React/RCTComponent.h>
@interface MyButton : UIButton
@property (nonatomic, strong) UIColor * textColor;
@property (nonatomic, assign) CGFloat fontSize;
@property (nonatomic, copy) NSString * title;
@property (nonatomic, strong) UIColor * bgColor;
//onChange 是原生组件提供给 rn 要回调的事件
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
@end
类中的这些属性,是要暴露给 RN 使用的属性.
2.新建一个继承RCTViewManager的类,这个类的主要作用就是导出要给 RN 使用的原生组件,包括组件的属性和方法.官网中关于该类的作用说明如下:
原生视图都需要被一个RCTViewManager的子类来创建和管理。这些管理器在功能上有些类似“视图控制器”,但它们本质上都是单例,
React Native只会为每个管理器创建一个实例。它们创建原生的视图并提供给RCTUIManager,RCTUIManager则会反过来委托它们在需要的时候去设置和更新视图的属性。RCTViewManager还会代理视图的所有委托,并给JavaScript发回对应的事件
#import <React/RCTViewManager.h>
@interface RNButton : RCTViewManager
@end
@implementation RNButton
RCT_EXPORT_MODULE()
- (UIView *)view {
MyButton * mbtn = [MyButton new];
[mbtn addTarget:self action:@selector(showInfo:) forControlEvents:UIControlEventTouchUpInside];
return mbtn;
}
- (void)showInfo:(MyButton *)button {
if (button.onChange) {
//当点击按钮的时候,会发出回调, rn 中可以对该回调作出响应
button.onChange(@{@"name": @"mike"});
}
}
//导出原生组件的属性,供 rn 直接使用
RCT_EXPORT_VIEW_PROPERTY(textColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(fontSize, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
RCT_EXPORT_VIEW_PROPERTY(bgColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
3.在 rn 中新建一个 Mybutton.js 文件(名字随意)
import React, { Component } from 'react';
import { requireNativeComponent } from 'react-native';
import {ColorPropType} from 'react-native';
import PropTypes from 'prop-types';
//requireNativeComponent:第一个参数是要导入的原生组件的文件名,要与项目中继承自RCTViewManager的类的名字一致,第二个参数可以为 null, 也可以为要封装的原生组件,这样可rn 可以在底层检查原生属性和包装类的属性类型是否一致.
注意:这里并没有直接使用导出的组件,而是将导出的组件重新封装成一个新组件,这样做逻辑比较清晰,而且可以在项目中复用,可以添加额外的组件.
var RNButton = requireNativeComponent('RNButton', UIButton)
export class Mybutton extends Component {
render() {
return (
<RNButton {...this.props}/>
)
}
}
Mybutton.propTypes = {
textColor:ColorPropType,
fontSize:PropTypes.number.isRequired,
title:PropTypes.string.isRequired,
bgColor:ColorPropType,
onChange:PropTypes.func.isRequired
};
4.在根组件中引入该组件,设置属性和方法
import {Mybutton} from './Mybutton.js'
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Mybutton
style={{width:80, height:40}}
textColor={'#3323FF'}
fontSize={15}
title={'hello world'}
bgColor={'#38BCFF'}
//点击按钮后会触发回调,event.nativeEvent中包含回传的对象
onChange={(event) => {
console.log(event.nativeEvent)
alert(event.nativeEvent.name)
}}
/>
</View>
);
}
}
5.至此,一个简单的例子完成.
网友评论