简体   繁体   English

如何修复 WebView 布局在 Xamarin Forms 上旋转后 iOS (WKWebView)

[英]How to fix WebView layout in Xamarin Forms after rotation on iOS (WKWebView)

I'm encountering problems getting a WebView to take up the whole screen properly in an iOS app using Xamarin Forms 4.8.0.1364 & in a ContentPage.我在使用 Xamarin Forms 4.8.0.1364 & 在 ContentPage 中使用 WebView 在 iOS 应用程序中正确占据整个屏幕时遇到问题。 The native control is WkWebView and am testing in an iPhone 12, iOS 14.1 Simulator.本机控件是 WkWebView,正在 iPhone 12、iOS 14.1 模拟器中进行测试。

Also, when the device rotates back into portrait orientation, the size of the WebView is wrong, or the content in the WebView is rendered improperly.此外,当设备旋转回纵向时,WebView 的大小不正确,或者 WebView 中的内容呈现不正确。

The XAML is as follows(note the BackgroundColor relative to the screencaps): XAML如下(注意BackgroundColor相对于screencaps):

<?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>

Note: I've tried a lot of things and have removed everything that didn't make a difference.注意:我已经尝试了很多东西并删除了所有没有影响的东西。 Have tried FillAndExpand on HorizontalOptions and VerticalOptions, as well as Star and Auto sizing on Grid columns/rows.已在 HorizontalOptions 和 VerticalOptions 上尝试过 FillAndExpand,以及在 Grid 列/行上尝试过 Star 和 Auto sizing。 I removed everything that didn't make a difference from the XAML. The results are:我删除了与 XAML 没有区别的所有内容。结果是:

Original Portrait(good enough:):原始肖像(足够好:): WebView 最初以纵向模式打开

After rotating 90 to landscape:旋转 90 度为横向后: 旋转90度横向后的WebView

After rotating back to portrait(content issue?):旋转回纵向后(内容问题?): 旋转回纵向后的 WebView

What I would like to see is the WebView taking up the whole screen w/ none of the various colors visible(Green, Blue, Black), and after rotation, the content should fit as expected.我想看到的是 WebView 占据了整个屏幕,而各种 colors 都不可见(绿色、蓝色、黑色),旋转后,内容应该符合预期。

I have also tried a Custom Renderer.我也尝试过自定义渲染器。

  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;
        }
      }

The results when calculating bounds in MyWebViewRenderer.LayoutSubviews, the results are:在MyWebViewRenderer.LayoutSubviews中计算bounds时的结果,结果为:

Initial page load in Portrait mode: (my height calculation is off?)纵向模式下的初始页面加载:(我的身高计算已关闭?)

初始页面加载,计算边界

After rotate to landscape(looks ok actually):旋转到横向后(实际上看起来还可以):

旋转到横向后,计算边界

After rotate back to portrait, the height calc is ok but somehow it's offset:旋转回纵向后,高度计算正常但不知何故偏移了:

旋转回纵向后,计算边界

Any suggestions?有什么建议么?

Thanks谢谢

Set the width of the page to follow the screen-width of the device and VerticalOptions to FillAndExpand .将页面宽度设置为与设备的屏幕宽度一致,并将VerticalOptions设置为FillAndExpand See also this answer :另请参阅此答案

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);
        }
    }
  }
}

Have a try to use WKUserScript to ensure the webpag was displayed with the same size as the screen size:尝试使用WKUserScript来确保网页的显示尺寸与屏幕尺寸相同:

public class MyWebViewRenderer : WkWebViewRenderer
{
    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null)
        {
            string jScript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";

            WKUserScript wkUScript = new WKUserScript(new NSString(jScript),WKUserScriptInjectionTime.AtDocumentEnd,true);
            WKUserContentController wkUController = new WKUserContentController();
            wkUController.AddUserScript(wkUScript);
            WKWebViewConfiguration webConfig = new WKWebViewConfiguration();

            this.Configuration.UserContentController = wkUController;
        }
    }   
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM