在iOS上为内部导航引发的Xamarin.Forms.WebView.Navigating事件

Zde*_*ica 4 c# webview ios xamarin xamarin.forms

假设您要阻止用户从您的Xamarin.Forms.WebView导航到外部页面.

public App ()
{
    var webView = new WebView
    {
        Source = new HtmlWebViewSource
        {
            Html = "<h1>Hello world</h1><a href='http://example.com'>Can't escape!</a><iframe width='420' height='315' src='https://www.youtube.com/embed/oHg5SJYRHA0' frameborder='0' allowfullscreen></iframe>"
        }
    };
    webView.Navigating += WebView_Navigating;

    MainPage = new ContentPage {
        Content = webView
    };
}

private void WebView_Navigating(object sender, WebNavigatingEventArgs e)
{
    // we don't want to navigate away from our page
    // open it in a new page instead etc.
    e.Cancel = true;
}
Run Code Online (Sandbox Code Playgroud)

这适用于Windows和Android.但在iOS上,它根本不加载!

在iOS上,即使从HtmlWebViewSource加载源代码时,也会引发Navigating事件,其URL看起来像 file:///Users/[user]/Library/Developer/CoreSimulator/Devices/[deviceID]/data/Containers/Bundle/Application/[appID]/[appName].app/

好吧,所以你可以用这样的东西解决这个问题:

private void WebView_Navigating(object sender, WebNavigatingEventArgs e)
{
    if (e.Url.StartsWith("file:") == false)
        e.Cancel = true;
}
Run Code Online (Sandbox Code Playgroud)

该页面最终在iOS上加载.好极了.可是等等!嵌入的YouTube视频无法加载!那是因为Navigating事件被引发用于嵌入式资源的内部导航,例如iframe甚至外部脚本(如Twitter <script charset="utf-8" type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>),但仅限于iOS!

我找不到确定导航事件是从内部导航引发还是因为用户单击链接的方法.

怎么解决这个问题?

hva*_*an3 5

我不确定是否可以开箱即用Xamarin Forms进行检测,但使用自定义渲染器可以轻松确定导航类型.在自定义iOS渲染器中,分配WebViewDelegate并在该Delegate类中,覆盖ShouldStartLoad()如下:

public class CustomWebViewRenderer : WebViewRenderer {

    #region Properties

    public CustomWebView CustomWebViewItem { get { return Element as CustomWebView; } }

    #endregion

    protected override void OnElementChanged(VisualElementChangedEventArgs e) {
        base.OnElementChanged(e);

        if(e.OldElement == null) {
            Delegate = new CustomWebViewDelegate(); //Assigning the delegate
        }
    }
}
internal class CustomWebViewDelegate : UIWebViewDelegate {

    public override bool ShouldStartLoad(UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType) {

        if(navigationType == UIWebViewNavigationType.LinkClicked) {
            //To prevent navigation when a link is click, return false
            return false;
        }

        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以将bool属性或甚至枚举备份到Xamarin表单WebView,这可以说明Navigating事件是来自被点击的链接还是其他内容,尽管也需要自定义渲染器.