我是Xamarin和iOS的新手。我试图在Xamarin Forms中创建一个呈现WkWebView的自定义渲染器。我希望当用户点击网页浏览中的链接时调用我的DidStartProvisionalNavigation()
方法,但这种方法没有发生,我也不知道为什么。我尝试使用Xlab' HybridViewRender作为参考。有人能告诉我当用户点击链接时如何让WkWebView调用DidStartProvisionalNavigation()
吗?感谢
这是我使用WkWebView的自定义IOS渲染器的源代码。
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, WKWebView>, IWKScriptMessageHandler
{
const string JavaScriptFunction = "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
WKUserContentController userController;
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "Uri")
Control.LoadRequest (new NSUrlRequest (new NSUrl (Element.Uri)));
}
protected override void OnElementChanged (ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged (e);
if (Control == null) {
userController = new WKUserContentController ();
var script = new WKUserScript (new NSString (JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
userController.AddUserScript (script);
userController.AddScriptMessageHandler (this, "invokeAction");
var config = new WKWebViewConfiguration { UserContentController = userController };
config.ApplicationNameForUserAgent += " MethodApp";
var webView = new WKWebView (Frame, config);
SetNativeControl (webView);
}
if (e.OldElement != null) {
userController.RemoveAllUserScripts ();
userController.RemoveScriptMessageHandler ("invokeAction");
var hybridWebView = e.OldElement as HybridWebView;
e.OldElement.onRefresh -= Refresh;
hybridWebView.Cleanup ();
}
if (e.NewElement != null) {
e.NewElement.onRefresh += Refresh;
//string fileName = Path.Combine (NSBundle.MainBundle.BundlePath, string.Format ("Content/{0}", Element.Uri));
if (Element.Uri != null)
Control.LoadRequest (new NSUrlRequest (new NSUrl (Element.Uri)));
}
}
public void Refresh(object sender, EventArgs ea) {
Control.Reload();
}
public void DidReceiveScriptMessage (WKUserContentController userContentController, WKScriptMessage message)
{
Element.InvokeAction (message.Body.ToString ());
}
[Export("webView:didStartProvisionalNavigation:")]
public void DidStartProvisionalNavigation(WKWebView webView, WKNavigation navigation)
{
Element.OnNavigating(webView.Url);
}
}
答案 0 :(得分:3)
您只需要添加以下行:
webView.NavigationDelegate = this;
代码之后:
var webView = new WKWebView (Frame, config);
也不要忘记改变:
public class HybridWebViewRenderer : ViewRenderer< HybridWebView,WKWebView>, IWKScriptMessageHandler, IWKNavigationDelegate
之后,您可以使用和覆盖DidStartProvisionalNavigation代码:
[Export("webView:didStartProvisionalNavigation:")]
public void DidStartProvisionalNavigation(WKWebView webView,WKNavigation navigation)
{
// When navigation starts, this gets called
Console.WriteLine("DidStartProvisionalNavigation");
}
答案 1 :(得分:2)
DidStartProvisionalNavigation
方法包含在IWKNavigationDelegate中,WKWebView
包含属性NavigationDelegate
您需要的只是一个自定义代表
public class MyNavigationDelegate : WKNavigationDelegate
{
private readonly HybridWebViewRenderer _renderer;
public MyNavigationDelegate(HybridWebViewRenderer renderer)
{
_renderer = renderer;
}
public override void DidFailProvisionalNavigation(WKWebView webView, WKNavigation navigation, NSError error)
{
// call methods of your renderer or its properties like
_renderer.Element.OnNavigating(webView.Url);
}
}
在您的渲染器中的webview上设置为NavigationDelegate
var webView = new WKWebView (Frame, config);
webView.NavigationDelegate = new MyNavigationDelegate(this);
答案 2 :(得分:1)
我相信
public override void DidStartProvisionalNavigation( WKWebView webView, WKNavigation navigation )
需要位于实现WKNavigationDelegate的委托类中,然后将其分配给webview的NavigationDelegate属性。
此论坛thread提供了有关使用WKWebView
的更多信息答案 3 :(得分:1)
我没有看到你为WKWebView设置了WeakNavigationDelegate。 XLabs的混合渲染器在这里做到了:
var webView = new WKWebView(Frame, config) { WeakNavigationDelegate = this };