【问题标题】:Xamarin Forms WKWebView size doesn't shrinkXamarin Forms WKWebView 大小不会缩小
【发布时间】:2020-08-24 09:51:11
【问题描述】:

我有一个自定义的WkWebView,我将视图的height 设置为html 内容的大小。

这在我初始化它时效果很好,但是当我将 WkWebViewsource 更改为更短的 html 时,问题就来了。

我已经在我的应用程序的 android 版本中遇到了this problem,我通过在EvaluateJavaScriptAsync 之前将 HeightRequest 设置为 0 来解决这个问题。这样,视野总是会变大。

我在 iOS 上尝试过同样的事情,但它保留了我拥有的最高内容。

例如:

如果我将WkWebView 的源设置为 200px 高度的 html 文件并将其更改为 1000px 的 html 文件,它可以正常工作并且我可以看到所有内容。但是,如果我尝试回到我的 200px html 文件,我会在下面得到一个 800px 的空白区域并保持 1000px 的高度。

目标是始终让WKWebView 的高度适应其内容的高度。

这是自定义渲染的当前版本

namespace MyNamespace.iOS.CustomControl
{
    public class AutoHeightWebViewRenderer : WkWebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            try
            {
                base.OnElementChanged(e);

                if (NativeView != null)
                {
                    var webView = (WKWebView)NativeView;
                    NavigationDelegate = new ExtendedWKWebViewDelegate(this);
                }
            }
            catch (Exception ex)
            {
                //Log the Exception  
            }   
        }
    }


    class ExtendedWKWebViewDelegate : WKNavigationDelegate
    {

        AutoHeightWebViewRenderer webViewRenderer;

        public ExtendedWKWebViewDelegate(AutoHeightWebViewRenderer _webViewRenderer = null)
        {
            webViewRenderer = _webViewRenderer ?? new AutoHeightWebViewRenderer();
        }

        public override async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
        {
            try
            {
                var _webView = webViewRenderer.Element as AutoHeightWebView;
                if (_webView != null)
                {
                    _webView.HeightRequest = 0d;
                    await Task.Delay(300);
                    var result = await _webView.EvaluateJavaScriptAsync("(function(){return document.body.scrollHeight;})()");
                    _webView.HeightRequest = Convert.ToDouble(result);
                }
            }
            catch (Exception ex)
            {
                //Log the Exception 
            }
        }

    }
}

编辑 1: 更清楚地说,我可以更改 webview 的高度,但我不知道高度,因为它总是返回迄今为止显示的最大 html 的高度。不管我使用_webView.EvaluateJavaScriptAsync("(function(){return document.body.scrollHeight;})()") 还是webView.ScrollView.ContentSize.Height

编辑 2: 这里有一个小样本来帮助理解问题。我有两个按钮和我的自定义 web 视图(用 40 HeightRequest 空 html 初始化)。 第一个按钮将 webview 的 Source 设置为 70px 长的 HTML。第二个将Source 设置为 280 像素长的 HTML。

在此示例中,我单击第一个按钮而不是第二个按钮,最后再次单击第一个按钮。您会看到在前 2 次点击时 webview 变大了。但是当我选择回第一个 html(从 280 像素到 70 像素)时,webview 应该会缩小,但它会保持 280 像素的长度。

第一个按钮(70px 长)

第二个按钮(280px 长)

回到第一个按钮(应该是 70 像素而不是 280 像素)。

模拟器和iOS设备都出现了问题。

【问题讨论】:

    标签: xamarin xamarin.forms xamarin.ios wkwebview custom-renderer


    【解决方案1】:

    您可以将webViewFrame 更改为height

    public override async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
    {
        try
        {
            var _webView = webViewRenderer.Element as WebView;
            if (_webView != null)
            {
    
                webView.Frame = new CGRect(webView.Frame.Location, new CGSize(webView.Frame.Size.Width, 0));
    
                var a = webView.ScrollView.ContentSize.Height;
                var b = await _webView.EvaluateJavaScriptAsync("(function(){return document.body.scrollHeight;})()");
    
                Console.WriteLine(a);
                Console.WriteLine(b);
    
                CGRect tempRect = webView.Frame;
    
                // for test                    
                webView.Frame = new CGRect(tempRect.Location.X, tempRect.Location.Y, tempRect.Size.Width, float.Parse(b));
    
            }
        }
        catch (Exception ex)
        {
            //Log the Exception 
        }
    }
    

    【讨论】:

    • 嗨,杰克!谢谢您的答复。我尝试了您的解决方案,但问题仍然存在。 (double)webView.ScrollView.ContentSize.Height 总是给出最高值。如果我使用EvaluateJavaScriptAsync,我会得到相同的结果。我可以使用HeightRequest 更改视图的高度。问题是我不知道 html 有多长(它的高度是多少)。返回的高度值是自创建以来在 webview 中显示的最大 html 的高度。简而言之,我需要一种方法来获取当前 html 的当前高度,而不是目前显示的最大高度。谢谢
    • 你是不是加了一个断点来查看webView.ScrollView.ContentSize.Height的值?长或短的 html 内容确实改变了我的值。
    • 是的,我做到了。我刚刚在带有 2 个按钮的单独视图中测试了我的自定义 web 视图。 1 将 webview 的源更改为 200px 长的 html,另一个按钮将源更改为 100px 长的 html。大小始终为 200px 长。 webView.ScrollView.ContentSize.Height 总是返回使用的最大 html。这发生在真正的 iPhone 设备上。
    • 我刚刚用一个例子和一些截图更新了帖子。
    • 你能试试我更新的代码,看看它是否适用于你吗?
    【解决方案2】:

    我遇到了同样的问题,CustomNavigationDelegate 也只会显示相同的大尺寸,即设备显示尺寸。

    我发现我已经在 XAML 的 init 部分和后面的代码中设置了这个,它以某种方式覆盖了后来基于内容的计算。

    在这里查看我的修复:https://stackoverflow.com/a/62409859/3443564

    【讨论】:

      猜你喜欢
      • 2017-06-30
      • 2018-06-09
      • 2019-11-14
      • 1970-01-01
      • 1970-01-01
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      相关资源
      最近更新 更多