我有一个我正在构建的本机应用程序,部分内容我实现了自己的自定义模块(在本例中是一个webview)。我设置好,一切正常,直到我在同一个屏幕上渲染两个相同的模块。
一旦我在同一个屏幕上有两个相同的模块,Objective-C中的代码将onChange方法调用回javascript不再执行,我可以通过Javascript更长时间与我的模块进行通信。
我注意到我的模块的每个实例都有一个标签或类似的东西,但我不知道应该怎么做才能解决这个问题。
更新
基本上我添加了一些代码,我可以看到问题是当新模块添加到屏幕时,它会覆盖前一个模块的回调。一旦新模块离开屏幕,Objective-C中的回调仍然是#34;重点关注"在最近渲染的模块上......
这可能与某些事情有关吗?
ReactNative.findNodeHandle(this.refs[WEB_VIEW]);
修改
我一直在查看一些开源代码,我想我已经缩小了问题范围。基本上我的模块由WebView和WebViewManager组成。 WebViews非常简单,只显示网络内容等,管理员负责控制他们的行为。
当我想从React Native调用模块上的方法时,我可以通过调用WebViewManager上的方法来实现:
scrollToTop() {
RNTWebViewManager.scrollToTop();
}
然后管理员将在Objective-C中调用相应的方法。但是,似乎当我一次在屏幕上有多个WebView实例时,管理员不知道要调用哪个实例,并且会调用放在屏幕上的最新实例。
在开源项目中,我看到他们通过传递引用并获取特定视图标记来执行某些操作,然后管理器使用它来调用WebView的正确实例,但我仍然想弄清楚如何实现这一点。
以下是我正在查看的项目的链接: https://github.com/CRAlpha/react-native-wkwebview
答案 0 :(得分:0)
好的,经过一段时间的研究,我终于想出了解决方案。基本上它与确保从React Native和Objective-C调用正确的组件有关。例如,在您的react本机组件中,您有一个函数:
executeJavascript(tag,js) {
RNTWebViewManager.executeJavascript(tag,js);
}
然后在你的RNTWebViewManager的Objective-C实现中你可以得到这样的东西:
RCT_EXPORT_METHOD(executeJavascript:(nonnull NSNumber *)reactTag with:(NSString *)js)
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RNWebView *> *viewRegistry) {
RNWebView *view = viewRegistry[reactTag];
[view evaluateJavaScript:js completionHandler:^(id _Nullable result, NSError * _Nullable error) {
if (result == nil) { result = @""; }
id outputError = (error) ? error.description : @"";
view.onChange(@{ @"result" : result, @"error": outputError, @"type" : @"javascript" });
}];
}];
}
注意executeJavascript函数如何获取标记,这是对您尝试调用该方法的当前视图的引用。因此,基本上您只需要在特定实例上执行方法时传递该标记号,您可以这样做:
getTag() {
return ReactNative.findNodeHandle(this.refs['RNWebView']);
}
在这种情况下,ref是'RNWebView',它会返回正确的标签,然后我可以使用它来调用该函数。希望我能解释这个问题。