我想讨论一下在JS端从IOS ViewManager/View调用本机方法时遇到的选项,这些选项不使用属性,而是直接调用方法。
选项A:
在ViewManager中实现一个方法,该方法搜索正确的视图并调用视图中给定的方法,如下所示:
func callMethodViaManager(_ node:NSNumber) {
DispatchQueue.main.async {
let myView = self.bridge.uiManager.view(forReactTag: node) as! MyView
myView.myMethod()
}
}
然后在JS端实现这样的处理程序:
const handleSomething = (e) => {
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(ref.current),
UIManager.SwiftComponent.Commands.callMethodViaManager,
[])
};
这只是对相关部分的简短总结,整个过程可以看到完整的细节,可能只是有点旧,但经过一些调整,可以使其与功能组件一起工作:
https://medium.com/@jjdanek/react-native-calling-class-methods-on-native-swift-views-521faf44f3dc
选项B:
对于此选项,让我们使用最佳场景,即可以通过委托(例如(或其他模式或Swift sugar在ViewManager上准备好所有必要的数据、设置等
使用NativeModules从JS端直接调用ViewManager中的Native方法,如下所示:
const handleSomething = (e) => {
NativeModules.MyViewManager.myMethod()
};
我找不到太多关于这个选项与正在桥接的Native View的相关信息,这种方式用于Native Module的显式桥接。我唯一能在哪里找到的东西:
React原生UI组件方法
或者像这样的指南:
https://teabreak.e-spres-oh.com/swift-in-react-native-the-ultimate-guide-part-1-modules-9bb8d054db03#4377
这两种方法我都试过了,乍一看似乎都有效。
所以我的问题是:
为什么选项A是更好的解决方案/选项,也是推荐或最常用的解决方案或选项?
选项B有什么问题或可能出现问题?
还有什么需要考虑的吗?
有没有一个更好的方法,不是槽属性?
选项B更灵活
如果使用选项A,则不能将Promise
和Callback
参数传递到本机端。
这在iOS中似乎是可能的,但在Android中则不然。
这是一个相关的问题。
React Native桥接API令人困惑
没有关于如何使用Promise
或Callback
调用原生UI方法的指南。
这里有一个关于如何通过调用原生UI实例方法将Promise
传递到本机端的示例。
SketchView...
只是我的示例模块名称。
class SketchViewModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
override fun getName() = "SketchViewModule"
private fun runCommandWithPromise(
viewId: Int, promise: Promise, handler: (view: SketchView) -> Unit
) {
reactApplicationContext.getNativeModule(UIManagerModule::class.java)?.let { uiManager ->
uiManager.addUIBlock {
(it.resolveView(viewId) as? SketchView)?.let { view ->
handler(view)
} ?: run {
promise.safeReject("[runCommandWithPromise] Cannot find View with UIManager")
}
}
}
}
...