首先新建一个简单的原生组件TestNativeView继承自UIView
再新建一个TestNativeViewManager 继承自RCTViewManager
我们一般在开发过程中组件需要拥有以下功能
1.RN通过属性传递的方式,渲染原生组件
2.原生组件能将事件传递到RN中
3.RN 能够直接调用原生方法完成操作
接下来我们上代码
TestNativeView.h
#import
#import
NS_ASSUME_NONNULL_BEGIN
@interface TestNativeView : UIView
-(void)nativeFunc:(NSDictionary *)obj;
@end
NS_ASSUME_NONNULL_END
TestNativeView.m
#import "TestNativeView.h"
#import "Masonry.h"
@interface TestNativeView()
@property(nonatomic, strong) NSString * title;
@property(nonatomic, strong) UITextView *contentTextView;
@property(nonatomic, strong) UIButton *btn;
@property(nonatomic, strong) RCTBubblingEventBlock onClick;
@end
@implementation TestNativeView
- (instancetype)init
{
self = [super init];
if (self) {
self.backgroundColor = [UIColor blueColor];
}
[self initSubView];
[self initLayout];
return self;
}
# pragma mark init
-(void)initSubView{
[self addSubview:self.contentTextView];
[self addSubview:self.btn];
}
-(void)initLayout{
[_contentTextView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self).offset(10);
make.size.mas_equalTo(CGSizeMake(200, 200));
}];
[_btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.contentTextView);
make.top.equalTo(self.contentTextView.mas_bottom);
make.size.mas_equalTo(CGSizeMake(80, 30));
}];
}
#pragma mark click
- (void)onClick: (id)sender{
if (!self.onClick) {
return;
}
self.onClick(@{@"msg":@"我点击了这个按钮"});
}
#pragma mark -func
- (void)nativeFunc:(NSDictionary *)obj{
NSLog(@"调用到了原生,获得值");
}
#pragma mark - getter setter
- (UIButton *)btn{
if (!_btn) {
_btn = [UIButton buttonWithType:UIButtonTypeCustom];
[_btn setTitle:@"点我" forState:UIControlStateNormal];
[_btn addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside];
}
return _btn;
}
- (UITextView *)contentTextView
{
if (!_contentTextView) {
_contentTextView = [[UITextView alloc] init];
[_contentTextView setFont:[UIFont systemFontOfSize:20]];
}
return _contentTextView;
}
- (void)setTitle:(NSString *)title
{
_title = title;
[_contentTextView setText:_title];
}
@end
TestNativeViewManager.h
#import
NS_ASSUME_NONNULL_BEGIN
@interface TestNativeViewManager : RCTViewManager
@end
NS_ASSUME_NONNULL_END
TestNativeViewManager.m
#import "TestNativeViewManager.h"
#import "TestNativeView.h"
#import
#import
@implementation TestNativeViewManager
RCT_EXPORT_MODULE(TestNativeView)
RCT_EXPORT_VIEW_PROPERTY(title,NSString)
RCT_EXPORT_VIEW_PROPERTY(onClick, RCTBubblingEventBlock)
- (UIView *)view
{
//创建组件实例
TestNativeView * viewInstance =[[TestNativeView alloc] init];
return viewInstance;
}
RCT_EXPORT_METHOD(nativeFunc:(nonnull NSNumber *)reactTag obj:(NSDictionary *)obj ) {
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) {
TestNativeView *view = viewRegistry[reactTag];
if (![view isKindOfClass:[TestNativeView class]]) {
RCTLogError(@"Invalid view returned from registry, expecting TestNativeView, got: %@", view);
} else {
dispatch_async(dispatch_get_main_queue(), ^{
TestNativeView *bannerView = (TestNativeView *)viewRegistry[reactTag];
[bannerView nativeFunc:obj];
});
}
}];
}
@end
RN端 创建js组件包裹原生组件
TestNativeView.js
import React, { Component } from 'react';
import { requireNativeComponent, View, findNodeHandle, UIManager } from 'react-native'
import PropTypes from 'prop-types'
var TestNativeViews = requireNativeComponent('TestNativeView')
export default class TestNativeView extends Component {
static PropTypes = {
...View.PropTypes,
title: PropTypes.string,
onClick: PropTypes.func
}
nativeFunc = (obj) => {
UIManager.dispatchViewManagerCommand(
findNodeHandle(this),
UIManager.getViewManagerConfig('TestNativeView').Commands.nativeFunc,
[
obj,
]
);
}
render() {
return
}
}
在页面中调用
this.TestNativeViewRefs = ref}
title={"这是一个原生组件"}
onClick={(event) => {
console.warn(event.nativeEvent.msg);
}}
style={{ width: 500, height: 500 }} />