objective-c - 以编程方式识别带有 Notch 的 iPhone

标签 objective-c xcode ios12 iphone-x

我正在尝试以编程方式识别带有缺口的 iPhone。我知道 screen.size 方法,但是当你有一个支持所有界面方向的通用应用程序时,它会变得一团糟(计算所有可能的变化)。因此,我正在寻找一种更简单、更优雅的方法来检测较新的 iPhone X 型号。

我在网上偶然发现了一种应该可行的方法。在其中,您测量安全区域的底部插入,如果它不为零,则您拥有 iPhone X 型号。这在理论上是有道理的,因为安全区域在 iPhone X 手机上不会到达屏幕底部,但在所有其他设备上都会到达。我这样检查:

if (@available( iOS 11.0, * )) {
    if ([[[UIApplication sharedApplication] keyWindow] safeAreaInsets].bottom > 0) {
        // iPhone with notch
    }
} else {
    // Regular iPhone
}

但是,这不起作用。有人可以指出我在实现中的错误或确认此方法是否可行吗?

最佳答案

我不得不深入挖掘,但找到了答案(我想向用户6788419大声喊叫,他的正确答案深藏在另一个线程中)。

首先,上面的代码是正确的。检查安全区域的底部插入是否大于零将准确识别带有凹口的 iPhone(截至撰写本文时)。所以,这是正确的:

if (@available( iOS 11.0, * )) {
    if ([[[UIApplication sharedApplication] keyWindow] safeAreaInsets].bottom > 0) {
        // iPhone with notch
    }
}

但是,将上述语句放在代码中的位置很重要,因为在第一个运行循环结束之前 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;
}

关于objective-c - 以编程方式识别带有 Notch 的 iPhone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55715380/

相关文章:

objective-c - Objective-C 中临时方法定义背后的基本原理

objective-c - 显示警告和时钟闹钟

ios - 如何调试Thread 1 : EXC_BAD_ACCESS (code=2, address=0x7ffee1ba8578的问题)

iOS 12 深度数据捕获错误代码 11800

ios12-从 NSHTTPURLResponse 获取 set-cookie

ios - 如何在其蒙版周围绘制 CALayer 边框?

iphone - Youtube 嵌入 html for uiwebview 不工作(在 iOS 4.2 iPhone 3G 上)

ios - Quickblox iOS 推送通知不起作用

c++ - 无法将 C++ 与 Xcode 5 链接起来

iOS 12 音乐应用的锁屏控制