IOS 混合应用 - 避开 iPhone 11 上的安全区域

IOS Hybrid App - Avoiding the safe area on iPhone 11

对于我的 IOS 混合应用程序,我以编程方式创建了一个 WKWebView,如下所示

- (void)viewDidLoad
    {
    [super viewDidLoad];

    _statBarH = [UIApplication sharedApplication].statusBarFrame.size.height ;
    appH = self.view.frame.size.height ;
    appW = self.view.frame.size.width ;
    webView = [[WKWebView alloc]initWithFrame:self.view.bounds configuration:theConfiguration];
    smallScreen = [deviceType hasPrefix:@"iPhone"];
    if (smallScreen && appW > appH) {webView.frame = CGRectMake(0, 0 , appW, appH);}
    else                            {webView.frame = CGRectMake(0, _statBarH, appW, appH - _statBarH);};
    };

我还更改了设备旋转时网页视图的大小,如下所示:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
    {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
        {
        appH = size.height ;
        appW = size.width  ;
        if (smallScreen && appW > appH) {webView.frame = CGRectMake(0, 0 , appW, appH);}
        else                            {webView.frame = CGRectMake(0, _statBarH, appW, appH - _statBarH);};
        }
     completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
        {
        [webView evaluateJavaScript:@"IOSOrientationChanged()" completionHandler:nil];
        }
     ];
    }

javascript 函数 IOSOrientationChanged 仅以纵向或横向格式重绘我的应用程序内容,从 javascript window.innerWidth 和 window.innerHeight

这种方法对我来说效果很好,直到 Apple 删除了 iPhone X 上的主页按钮,11 ...

在这些较新的手机上发生的事情(至少在 XCode 11 IOS 13 模拟器中是这样,因为我真的买不起)是当第一次创建网络视图时,它尊重上安全区,但不尊重下安全区。

然而,当我在模拟器中旋转设备时,webview 尊重两个安全区域。

对于iPhone11,变量appW和appH在竖屏中分别为414和896,在横屏中分别为896和414。变量 _statBarH 纵向为 44,横向为 0。

但是在网络视图中,纵向 window.innerHeight 最初设置为 852 (896-44),但旋转后设置为 838。

有人能告诉我我做错了什么吗?是否某些内部视图约束不是第一次强制执行,而是轮换后强制执行?

解决这个问题的方法有两个

  1. 首先在 viewDidAppear 中创建 WKWebView,而不是在 viewDidLoad 中,因为直到 viewDidAppear 才能以编程方式访问 safeAreaInserts 值

  2. 其次,在创建WKWebView框架时使用safeAreaInserts中的值,如下

    smallScreen = [deviceType hasPrefix:@"iPhone"];
    topMargin   = [UIApplication sharedApplication].statusBarFrame.size.height ;
    if (@available(iOS 11, *)) topMargin = self.view.safeAreaInsets.top ;
    bottomMargin = 0 ;
    if (@available(iOS 11, *)) bottomMargin = self.view.safeAreaInsets.bottom ;
    
    int top    = (smallScreen && appW > appH)? 0    : topMargin ;
    int height = (smallScreen && appW > appH)? appH : appH - topMargin - bottomMargin ;
    NSLog (@"Top %d, Height %d",top,height);
    
    webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, top , appW, height) configuration:theConfiguration];