我不得不费些功夫查找,但最终找到了答案(我想向用户6788419大喊一声,他正确的答案被深埋在另一个线程中)。
首先,上面的代码是正确的。检查安全区域底部插入是否大于零将准确地识别带有刘海的iPhone(截至本文撰写时)。所以,这是正确的:
if (@available( iOS 11.0, * )) {
if ([[[UIApplication sharedApplication] keyWindow] safeAreaInsets].bottom > 0) {
}
}
然而,这句话放置在代码中的位置很重要,因为在第一个运行循环结束之前,UIWindow是不可用的。这意味着,如果您在viewDidLoad或它之前(例如,在init中)检查刘海屏幕,底部插入将始终为零。
如果您和我一样需要此检查来设置主视图,则可以将所有设置移动到单独的函数中(例如postViewDidLoad),并在viewDidLoad完成后调用它:
[self performSelector:@selector(postViewDidLoad) withObject:nil afterDelay:0.0f]
或者,作为另一种选择,你可以将其封装起来:
dispatch_async(dispatch_get_main_queue(), ^{
// Check notch here
});
更新:针对iOS 13及以上版本的代码(执行相同操作)。在调用函数时,“areaPosition”是一个字符串参数。“top”检查缺口,其他所有内容都检查底部主页指示器的存在。
- (UIWindow *) keyWindow {
UIWindow *foundWindow = nil;
NSArray *windows = [[UIApplication sharedApplication]windows];
for (UIWindow *window in windows) {
if (window.isKeyWindow) {
foundWindow = window;
break;
}
}
return foundWindow;
}
- (BOOL) checkSafeArea:(NSString *)areaPosition {
if (@available(iOS 13.0, *)) {
if ([areaPosition isEqualToString:@"top"]) {
return [self keyWindow].safeAreaInsets.top > 20.0f;
} else {
return [self keyWindow].safeAreaInsets.bottom > 0.0f;
}
} else {
if ([areaPosition isEqualToString:@"top"]) {
return [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top > 20.0f;
} else {
return [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.bottom > 0.0f;
}
}
return NO;
}