ios - 如何在 iOS 上旋转后修复 Xamarin Forms 中的 WebView 布局(WKWebView)
问题描述
我在使用 Xamarin Forms 4.8.0.1364 和 ContentPage 的 iOS 应用程序中让 WebView 正确占据整个屏幕时遇到问题。本机控件是 WkWebView,正在 iPhone 12、iOS 14.1 模拟器中进行测试。
此外,当设备旋转回纵向时,WebView 的大小错误,或者 WebView 中的内容渲染不正确。
XAML 如下(注意相对于屏幕截图的 BackgroundColor):
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModel="clr-namespace:MyCompany.MyApp.ViewModels;assembly=MyAssembly"
x:Class="MyCompany.MyApp.Views.MyWebViewPage"
BackgroundColor="Green" >
<ContentPage.BindingContext>
<viewModel:MyPageViewModel URL="https://login.somepage.com" />
</ContentPage.BindingContext>
<ContentPage.Content>
<Grid BackgroundColor="Blue">
<WebView x:Name="WebView"
BackgroundColor="Black"
Source="{Binding URL}"
Cookies="{Binding Cookies}">
</WebView>
</Grid>
</ContentPage.Content>
</ContentPage>
注意:我已经尝试了很多东西,并删除了所有没有影响的东西。已经在 HorizontalOptions 和 VerticalOptions 上尝试过 FillAndExpand,以及在 Grid 列/行上使用 Star 和 Auto sizing。我删除了与 XAML 没有区别的所有内容。结果是:
我想看到的是 WebView 占据了整个屏幕,没有各种颜色可见(绿色、蓝色、黑色),并且在旋转后,内容应该符合预期。
我也尝试过自定义渲染器。
public class MyWebViewRenderer : WkWebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;
}
}
public override void LayoutSubviews()
{
Bounds = CalculateBounds();
base.LayoutSubviews();
}
private CGRect CalculateBounds()
{
var screenBounds = UIScreen.MainScreen.Bounds;
var statusBarHeight = UIApplication.SharedApplication.StatusBarFrame.Height;
nfloat navBarHeight = 0;
var uiNavController = Window?.RootViewController as UINavigationController;
if (uiNavController?.TopViewController != null)
{
navBarHeight = uiNavController.NavigationBar.Bounds.Height;
}
var adjustedHeight = statusBarHeight + navBarHeight;
var bounds = new CGRect(screenBounds.X, screenBounds.Y + adjustedHeight,
screenBounds.Width, screenBounds.Height - adjustedHeight);
return bounds;
}
}
MyWebViewRenderer.LayoutSubviews中计算bounds时的结果,结果为:
纵向模式下的初始页面加载:(我的高度计算已关闭?)
旋转到横向后(实际上看起来还可以):
旋转回纵向后,高度计算没问题,但不知何故它偏移了:
有什么建议么?
谢谢
解决方案
将页面的宽度设置为跟随设备的屏幕宽度并VerticalOptions
设置为FillAndExpand
. 另请参阅此答案:
using Foundation;
using WebKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using MyNamespace.iOS.Renderers;
[assembly: ExportRenderer(typeof(WebView), typeof(MyWebViewRenderer))]
namespace MyNamespace.iOS.Renderers
{
public class MyWebViewRenderer : WkWebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
WebView webView = Element as WebView;
webView.VerticalOptions = LayoutOptions.FillAndExpand;
//width=device-width sets the width of the page to follow the screen-width of the device
string jScript = @"" +
"var meta = document.createElement('meta'); " +
"meta.setAttribute('name', 'viewport');" +
"meta.setAttribute('content', 'width=device-width');" +
"document.getElementsByTagName('head')[0].appendChild(meta);";
var userScript = new WKUserScript((NSString)jScript, WKUserScriptInjectionTime.AtDocumentEnd, true);
this.Configuration.UserContentController.AddUserScript(userScript);
}
}
}
}
推荐阅读
- python - 从源库构建的导入到 python
- reactjs - Typescript,是否可以在没有某种类型的情况下扩展接口?
- javascript - jquery-如何验证表单的每个标签页?
- sql - 在序列函数 PrestoSQL 中使用子查询
- python - 如何将命令行参数传递给在 vscode 中运行的 pytest 测试
- javascript - 模态打开时使抽屉可见。反应原生
- google-data-studio - 基于其他计算字段创建计算字段
- java - 如何修复 GridLayout/GridBagConstraints 中的错误?
- python - Python Kivy UnicodeEncodeError
- gradle - Vaadin Gradle 插件:任务 vaadinBuildFrontend 失败并出现依赖错误