【问题标题】:Xamarin Forms Handle Hyperlinks in Webview Navigating issueXamarin 表单处理 Webview 导航问题中的超链接
【发布时间】:2016-11-26 09:37:21
【问题描述】:

我正在开发一个应用,其中包含来自我们 CMS 的一些内容页面 需要显示到 WebView 中,因为它们有 HTML,其中包含一些超链接

我正在控制超链接,它在 android 上按预期工作 我用 Xamarin.Forms.WebView 事件的Navigating 来做这件事

我可以使用e.Url 将用户发送到内部页面。

示例:

public class HybridWebView : WebView
{
    public String Code { get; set; }

    public HybridWebView()
    {
        Navigating += HybridWebView_Navigating;
    }


    private void HybridWebView_Navigating(object sender, WebNavigatingEventArgs e)
    {
       if(e.Url.EndsWith(".aspx")
       {
          var CMS = new CMSView(e.Code, null);
          Navigation.PushAsync(CMS);
          e.Cancel = true;
       }
    }
}

请注意,这很好用!

问题是:

当我在 iOS 上尝试这个时,我得到了一个空白/白色 WebView。 我试图在 iOS 上创建一个 CustomRenderer,但由于我将 WebView 子类化以对其进行自定义,因此我无法访问属性 Code 例如。

如何访问 ios 自定义渲染器中的属性?我知道 e.NewElementShouldStartLoad 需要 UIWebView 而不是我的自定义 HybridWebView。

有没有人有任何提示或想法让我可以达到这个目标。

提前致谢

【问题讨论】:

    标签: c# xamarin xamarin.ios xamarin.android xamarin.forms


    【解决方案1】:

    在您的客户渲染器(我假设是 WebViewRenderer 的子类)中,您可以将 e.newElement 转换为您的 HybridWebView 类型,例如:

    HybridWebView wv = e.NewElement as HybridWebView;
    

    那么您应该可以使用wv.Code 访问您的Code 属性。

    此外,WebViewRendererNativeView 属性将为您提供 iOS 原生 UIView 以供使用。您应该可以毫无问题地将其转换为 UIWebView。例如:

    UIWebView nativeUIWebView = NativeView as UIWebView;
    

    我希望这会有所帮助!

    【讨论】:

    • Thnx jgoldberger 我不需要转换 e.NewElement,因为它知道它来自 Hybridview 的类型,但是我如何使用应该将 UIWebView 作为参数的 ShouldStartLoad,我需要在那里使用 Hybridview。
    • 除非我遗漏了什么,否则我提到的 NativeView 应该是基础渲染器为您的 HybridWebView 创建的。所以这应该是与 ShouldStartLoad 一起使用的 UIWebView,除非我有误解?
    【解决方案2】:

    如果您想使用ShouldStartLoad,您需要为正在使用的本机UIWebView 实现自定义UIWebViewDelegate。这可能会变得棘手,因为如果将现有委托替换为自定义委托,您将失去 Xamarin.Forms WebView 提供的一些内置功能。以下是我用来充分利用两者的策略:

    [assembly: ExportRenderer (typeof (WebView), typeof (CustomWebViewRenderer))]
    public class CustomWebViewRenderer : WebViewRenderer
    {
        protected override void OnElementChanged (VisualElementChangedEventArgs e)
        {
            base.OnElementChanged (e);
    
            if (e.OldElement == null) {
    
                // Need to capture the existing one so we don't loose functionality 
                // that Xamarin.Forms already has
                var existingDelegate = Delegate;
    
                // Make sure to pass the existing one to the new one
                Delegate = new MyCustomWebViewDelegate(existingDelegate);
            }
        }
    }
    
    public class MyCustomWebViewDelegate : UIWebViewDelegate
    {
        readonly UIWebViewDelegate existingDelegate;
    
        public MyCustomWebViewDelegate(UIWebViewDelegate existing)
        {
            existingDelegate = existing;
        }
    
        public override bool ShouldStartLoad (UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType)
        {
            // You can customize this instead of returning the existingDelegate method
            return existingDelegate.ShouldStartLoad(webView, request, navigationType);
        }
    
        public override void LoadFailed (UIWebView webView, NSError error)
        {
            existingDelegate.LoadFailed(webView, error);
        }
    
    
        public override void LoadingFinished (UIWebView webView)
        {
            existingDelegate.LoadingFinished(webView);
        }
    
    
        public override void LoadStarted (UIWebView webView)
        {
            existingDelegate.LoadStarted(webView);
        }
    
    }
    

    注意* 在 iOS 上,WebViewRenderer 直接继承自 UIWebView,因此您不需要使用 Control 属性。您是 UIWebView 的直接子类,可以访问您期望的属性。见源here

    您可以将自定义登录添加到MyCustomWebViewDelegate.ShouldStartLoad 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-26
      • 1970-01-01
      • 2017-06-15
      • 2014-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-06
      相关资源
      最近更新 更多