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。
有人能告诉我我做错了什么吗?是否某些内部视图约束不是第一次强制执行,而是轮换后强制执行?
解决这个问题的方法有两个
首先在 viewDidAppear 中创建 WKWebView,而不是在 viewDidLoad 中,因为直到 viewDidAppear 才能以编程方式访问 safeAreaInserts 值
其次,在创建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];
对于我的 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。
有人能告诉我我做错了什么吗?是否某些内部视图约束不是第一次强制执行,而是轮换后强制执行?
解决这个问题的方法有两个
首先在 viewDidAppear 中创建 WKWebView,而不是在 viewDidLoad 中,因为直到 viewDidAppear 才能以编程方式访问 safeAreaInserts 值
其次,在创建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];