首先新建一個(gè)簡單的原生組件TestNativeView繼承自UIView
再新建一個(gè)TestNativeViewManager 繼承自RCTViewManager
我們一般在開發(fā)過程中組件需要擁有以下功能
1.RN通過屬性傳遞的方式虐杯,渲染原生組件
2.原生組件能將事件傳遞到RN中
3.RN 能夠直接調(diào)用原生方法完成操作
接下來我們上代碼
TestNativeView.h
#import <UIKit/UIKit.h>
#import <React/RCTViewManager.h>
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":@"我點(diǎn)擊了這個(gè)按鈕"});
}
#pragma mark -func
- (void)nativeFunc:(NSDictionary *)obj{
NSLog(@"調(diào)用到了原生部念,獲得值");
}
#pragma mark - getter setter
- (UIButton *)btn{
if (!_btn) {
_btn = [UIButton buttonWithType:UIButtonTypeCustom];
[_btn setTitle:@"點(diǎn)我" 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 <React/RCTViewManager.h>
NS_ASSUME_NONNULL_BEGIN
@interface TestNativeViewManager : RCTViewManager
@end
NS_ASSUME_NONNULL_END
TestNativeViewManager.m
#import "TestNativeViewManager.h"
#import "TestNativeView.h"
#import <React/RCTUIManager.h>
#import <UIKit/UIKit.h>
@implementation TestNativeViewManager
RCT_EXPORT_MODULE(TestNativeView)
RCT_EXPORT_VIEW_PROPERTY(title,NSString)
RCT_EXPORT_VIEW_PROPERTY(onClick, RCTBubblingEventBlock)
- (UIView *)view
{
//創(chuàng)建組件實(shí)例
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<NSNumber *, TestNativeView *> *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端 創(chuàng)建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 <TestNativeViews {...this.props} />
}
}
在頁面中調(diào)用
<Button
onPress={() => {
this.setState({
title: "改變了title"
})
this.TestNativeViewRefs && this.TestNativeViewRefs.nativeFunc({ name: '111' })
}
}
>
<Text>{this.state.title}</Text>
</Button>
<TestNativeView
ref={ref => this.TestNativeViewRefs = ref}
title={"這是一個(gè)原生組件"}
onClick={(event) => {
console.warn(event.nativeEvent.msg);
}}
style={{ width: 500, height: 500 }} />