如何在 React Native 中访问原生 UI 组件的实例方法
How to access native UI components' instance methods in React Native
我们可以通过使用 RCT_EXPORT_VIEW_PROPERTY
.
导出本机属性来控制自定义本机 UI 组件的属性
但是如何导出原生 UI 组件的实例方法?
感谢@alinz's suggestion。
这可以在自定义本机组件的视图管理器中完成。
- Obj-c 端:在本机视图管理器中公开这样的本机方法:
关键是传入reactTag
,也就是对原生组件的引用
MyCoolViewManager.m
:
RCT_EXPORT_METHOD(myCoolMethod:(NSNumber *)reactTag callback:(RCTResponseSenderBlock)callback) {
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
MyCoolView *view = viewRegistry[reactTag];
if (![view isKindOfClass:[MyCoolView class]]) {
RCTLogMustFix(@"Invalid view returned from registry, expecting MyCoolView, got: %@", view);
}
// Call your native component's method here
[view myCoolMethod];
}];
}
- JS端:在react组件中添加API class:
MyCoolView.js
:
var React = require('react-native');
var NativeModules = require('NativeModules');
var MyCoolViewManager = NativeModules.MyCoolViewManager;
var findNodeHandle = require('findNodeHandle');
class MyCoolView extends React.Component{
// ...
myCoolMethod() {
return new Promise((resolve, reject) => {
MyCoolViewManager.myCoolMethod(
findNodeHandle(this),
(error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
}
);
});
}
}
我不是 Objective C 专家,而是 Swift 开发人员。
我最好使用这种方式只是为了可读性(也许 Obj-C 有缺点?):
- 在管理器中:在私有实例中存储对视图的引用 属性
- 这将有助于调用您的视图方法
Obj-C 端 - 组件管理器:
@implementation RNAnalogClockManager {
RNAnalogClock* _AnalogClock;
}
RCT_EXPORT_MODULE()
- (UIView *)view
{
// keep a reference to the view before returning it
_AnalogClock = [[RNAnalogClock alloc] init];
return _AnalogClock;
}
// export method and easily call view method
RCT_EXPORT_METHOD(startRealTime) {
[_AnalogClock startRealTime];
};
JS端不变
NOTE: I don't need callback in my example but it does not change the principle it is just another parameter.
我们可以通过使用 RCT_EXPORT_VIEW_PROPERTY
.
但是如何导出原生 UI 组件的实例方法?
感谢@alinz's suggestion。
这可以在自定义本机组件的视图管理器中完成。
- Obj-c 端:在本机视图管理器中公开这样的本机方法:
关键是传入reactTag
,也就是对原生组件的引用
MyCoolViewManager.m
:
RCT_EXPORT_METHOD(myCoolMethod:(NSNumber *)reactTag callback:(RCTResponseSenderBlock)callback) {
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
MyCoolView *view = viewRegistry[reactTag];
if (![view isKindOfClass:[MyCoolView class]]) {
RCTLogMustFix(@"Invalid view returned from registry, expecting MyCoolView, got: %@", view);
}
// Call your native component's method here
[view myCoolMethod];
}];
}
- JS端:在react组件中添加API class:
MyCoolView.js
:
var React = require('react-native');
var NativeModules = require('NativeModules');
var MyCoolViewManager = NativeModules.MyCoolViewManager;
var findNodeHandle = require('findNodeHandle');
class MyCoolView extends React.Component{
// ...
myCoolMethod() {
return new Promise((resolve, reject) => {
MyCoolViewManager.myCoolMethod(
findNodeHandle(this),
(error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
}
);
});
}
}
我不是 Objective C 专家,而是 Swift 开发人员。
我最好使用这种方式只是为了可读性(也许 Obj-C 有缺点?):
- 在管理器中:在私有实例中存储对视图的引用 属性
- 这将有助于调用您的视图方法
Obj-C 端 - 组件管理器:
@implementation RNAnalogClockManager {
RNAnalogClock* _AnalogClock;
}
RCT_EXPORT_MODULE()
- (UIView *)view
{
// keep a reference to the view before returning it
_AnalogClock = [[RNAnalogClock alloc] init];
return _AnalogClock;
}
// export method and easily call view method
RCT_EXPORT_METHOD(startRealTime) {
[_AnalogClock startRealTime];
};
JS端不变
NOTE: I don't need callback in my example but it does not change the principle it is just another parameter.