StackOverflow 上有很多关于检测 iPhone 设备屏幕上是否有凹口的问题,例如这个。答案几乎总是建议使用safeAreaInsets
顶部窗口的属性。我在我的应用程序中使用它来确定是否应该显示状态栏,从prefersStatusBarHidden
当前显示的视图控制器的方法。我想在有缺口时显示状态栏,但在没有缺口时不显示。它在我的所有测试中都运行良好,但对于某些客户来说,状态栏有时会消失,即使他们使用的是带有缺口的设备(iPhone 12 Pro Max)。
我调查了一下,我认为问题可能是由对 的递归调用引起的safeAreaInsets
,请参见以下调用堆栈:
这有点道理。为了确定安全区域需要多大,iOS 需要知道是否需要显示状态栏。因此,它调用prefersStatusBarHidden
可见视图控制器,然后使用安全区域来确定......
尽管进行了递归调用,但它在测试中仍然适用于我,但如前所述,它有时对某些用户来说会失败。我需要使用prefersStatusBarHidden
,因为在顶层应用程序包含一个UITabBarController
,只有一个选项卡隐藏状态栏。其他选项卡应始终显示状态栏,与是否有缺口无关。
我考虑过使用sysctlbyname
with"hw.machine"
参数检查设备类型,然后使用映射表来获取缺口/无缺口结果。但这有一个缺点,即需要为每个新的 iPhone 型号更新映射表,并且它不能在总是返回 Mac 机器名称的模拟器上工作。
任何想法如何以更好的方式解决这个问题?我可以简单地避免递归调用,但这会解决问题吗?
我现在确定缺口的代码(Objective-C):
- (bool) hasTopNotch
{
if (@available(iOS 11.0, *)) {
UIWindow *window = [UIApplication sharedApplication].delegate.window;
UIEdgeInsets insets = window.safeAreaInsets;
return insets.top >= 44;
} else {
return NO;
}
}