Xamarin Forms WKWebView 大小不会缩小
Xamarin Forms WKWebView size doesn't shrink
我有一个自定义 WkWebView
,我将视图的 height
设置为 html 内容的大小。
这在我初始化它时效果很好,但是当我将 WkWebView
的 source
更改为较短的 html.
时,问题就来了
我已经在 android 版本的应用程序中遇到了 ,我通过在 EvaluateJavaScriptAsync
之前将 HeightRequest 设置为 0 来解决这个问题。这样视野就会变大。
我用 iOS 尝试过同样的事情,但它保留了我拥有的最高内容。
例如:
如果我将 WkWebView
的源设置为 200px 高度的 html 文件并将其更改为 1000px 的 html 文件,它工作正常,我可以查看全部内容。但是,如果我尝试回到我的 200px html 文件,我会在下面得到一个 800px 的空白 space 并保持 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:
这里有一个小例子来帮助理解这个问题。我有两个按钮和我的自定义 webview(初始化为 40 HeightRequest
空 html)。
第一个按钮将 webview 的 Source
设置为 70px 长 HTML。第二个将 Source
设置为 280px 长 HTML.
在这个例子中,我点击了第一个按钮而不是第二个按钮,最后又回到了第一个按钮。您会看到 webview 在前 2 次点击时变大。但是当我选择第一个 html 时,webview 应该会缩小(从 280px 到 70px),但它会保持 280px 的长度。
第一个按钮(70px 长)
第二个按钮(280px 长)
返回第一个按钮(长度应为 70 像素而不是 280 像素)。
模拟器和 iOS 设备均出现问题。
您可以更改 webView
的 Frame
来更改 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
}
}
我遇到了同样的问题,CustomNavigationDelegate 也只会显示相同的大尺寸,即设备显示尺寸。
我发现我已经在 XAML 的初始化部分和后面的代码中设置了它,它以某种方式覆盖了后来基于内容的计算。
在这里查看我的修复:
我有一个自定义 WkWebView
,我将视图的 height
设置为 html 内容的大小。
这在我初始化它时效果很好,但是当我将 WkWebView
的 source
更改为较短的 html.
我已经在 android 版本的应用程序中遇到了 EvaluateJavaScriptAsync
之前将 HeightRequest 设置为 0 来解决这个问题。这样视野就会变大。
我用 iOS 尝试过同样的事情,但它保留了我拥有的最高内容。
例如:
如果我将 WkWebView
的源设置为 200px 高度的 html 文件并将其更改为 1000px 的 html 文件,它工作正常,我可以查看全部内容。但是,如果我尝试回到我的 200px html 文件,我会在下面得到一个 800px 的空白 space 并保持 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:
这里有一个小例子来帮助理解这个问题。我有两个按钮和我的自定义 webview(初始化为 40 HeightRequest
空 html)。
第一个按钮将 webview 的 Source
设置为 70px 长 HTML。第二个将 Source
设置为 280px 长 HTML.
在这个例子中,我点击了第一个按钮而不是第二个按钮,最后又回到了第一个按钮。您会看到 webview 在前 2 次点击时变大。但是当我选择第一个 html 时,webview 应该会缩小(从 280px 到 70px),但它会保持 280px 的长度。
第一个按钮(70px 长)
第二个按钮(280px 长)
返回第一个按钮(长度应为 70 像素而不是 280 像素)。
模拟器和 iOS 设备均出现问题。
您可以更改 webView
的 Frame
来更改 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
}
}
我遇到了同样的问题,CustomNavigationDelegate 也只会显示相同的大尺寸,即设备显示尺寸。
我发现我已经在 XAML 的初始化部分和后面的代码中设置了它,它以某种方式覆盖了后来基于内容的计算。
在这里查看我的修复: