2016-04-05 12 views
1

Ich bin neu in Xamarin und iOS. Ich versuche, einen benutzerdefinierten Renderer in Xamarin Forms zu erstellen, der WkWebView rendert. Ich möchte meine DidStartProvisionalNavigation() Methode aufgerufen werden, wenn der Benutzer auf einen Link in der Webansicht tippt, aber das ist nicht passiert, und ich weiß nicht warum. Ich versuche Xlabs HybridViewRender als Referenz zu verwenden. Kann mir jemand sagen, wie ich WkWebView dazu bringen kann, DidStartProvisionalNavigation() anzurufen, wenn ein Benutzer auf einen Link klickt? DankeWwWebView Navigieren Ereignis anhören

Hier ist der Quellcode meines benutzerdefinierten IOS-Renderers, der WkWebView verwendet.

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); 
     } 
    } 

Antwort

2

Die DidStartProvisionalNavigation Methode in der IWKNavigationDelegate enthalten ist und WKWebView hat die Eigenschaft NavigationDelegate

Alles, was Sie benötigen, sollten Sie eine benutzerdefinierte Delegate

ist
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); 
    } 
} 

, die in als NavigationDelegate auf Ihrem webview gesetzt Ihr Renderer

var webView = new WKWebView (Frame, config); 
webView.NavigationDelegate = new MyNavigationDelegate(this); 
1

Ich glaube, dass

public override void DidStartProvisionalNavigation(WKWebView webView, WKNavigation navigation) 

in einem Delegierten Klasse sein muss, die WKNavigationDelegate implementiert, dass Sie dann NavigationDelegate auf Ihre webview Eigenschaft zuweisen.

Dieses Forum thread hat einige weitere Informationen über WKWebView mit

2

Sie müssen nur diese Zeile hinzufügen:

webView.NavigationDelegate = this; 

nach dem Code:

var webView = new WKWebView (Frame, config); 

auch don‘ t vergessen zu ändern:

public class HybridWebViewRenderer : ViewRenderer< HybridWebView,WKWebView>, IWKScriptMessageHandler, IWKNavigationDelegate 

Danach können Sie den DidStartProvisionalNavigation Code verwenden und außer Kraft setzen:

[Export("webView:didStartProvisionalNavigation:")] 
public void DidStartProvisionalNavigation(WKWebView webView,WKNavigation navigation) 
{ 
// When navigation starts, this gets called 
Console.WriteLine("DidStartProvisionalNavigation"); 
} 
Verwandte Themen