现在我有用于Web视图渲染器的代码,如下所示:
public sealed class MyWebViewRenderer : ViewRenderer<WebView, WKWebView>, IWKScriptMessageHandler
{
private const string ScriptMessageHandlerName = "native";
private WKUserContentController userController;
private WKWebView m_NativeView;
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
var visualWebView = (ImWebView)Element;
if (Control == null && e.NewElement != null)
{
this.userController = new WKUserContentController();
var config = new WKWebViewConfiguration
{
UserContentController = this.userController
};
this.userController.AddScriptMessageHandler(this, ScriptMessageHandlerName);
m_NativeView = new WKWebView(this.Frame, config) { WeakNavigationDelegate = new ImNavigationDelegate()};
SetNativeControl(m_NativeView);
}
public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
{
...
}
}
此类允许我从 JS 接收消息。但是现在我想收到页面加载失败的消息。我找到了唯一的方法 - 使用 Xamarin.Forms.Platform.iOS.WebViewRenderer
作为我的渲染器的基类并使用
public sealed class MyWebViewRenderer : Xamarin.Forms.Platform.iOS.WebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
var visualWebView = (ImWebView)Element;
if (this.ViewController == null && e.NewElement != null)
{
base.Delegate = new CustomNavigationDelegate() { Control = visualWebView };
}
...
}
public class CustomNavigationDelegate : UIWebViewDelegate
{
public ImWebView Control { get; set; }
public override void LoadFailed(UIWebView webView, NSError error)
{
...
}
}
}
加载失败捕获运行良好,但是使用此代码,我无法从JS获取消息。有没有办法在一个类中从JS代码中获取LoadFailed事件和消息?
我建议您继续使用从WKWebView
继承的渲染器。我们可以在WKNavigationDelegate
中使用DidFailNavigation
虚拟方法在导航时出错时获取回调。你可以像下面这样使用它
public sealed class MyWebViewRenderer : ViewRenderer<WebView, WKWebView>, IWKScriptMessageHandler
{
private const string ScriptMessageHandlerName = "native";
private WKUserContentController userController;
private WKWebView m_NativeView;
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
var visualWebView = (ImWebView)Element;
if (Control == null && e.NewElement != null)
{
this.userController = new WKUserContentController();
var config = new WKWebViewConfiguration
{
UserContentController = this.userController
};
this.userController.AddScriptMessageHandler(this, ScriptMessageHandlerName);
m_NativeView = new WKWebView(this.Frame, config) { WeakNavigationDelegate = new NavigationDelegate()};
SetNativeControl(m_NativeView);
}
}
public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
{
}
}
public class NavigationDelegate : WKNavigationDelegate
{
public override void DidFailNavigation( WKWebView webView, WKNavigation navigation, NSError error )
{
// If navigation fails, this gets called
}
}