ios - 检测设备是否为 iPhone X

我的 iOS 应用为 UINavigationBar 使用自定义高度,这会导致新 iPhone X 出现一些问题。

是否有人已经知道如何可靠以编程方式(在 Objective-C 中)检测应用是否在 iPhone X 上运行?

编辑:

当然可以检查屏幕的大小,但是,我想知道是否有像 TARGET_OS_IPHONE 这样的“内置”方法来检测 iOS...

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
    CGSize screenSize = [[UIScreen mainScreen] bounds].size;
    if (screenSize.height == 812)
        NSLog(@"iPhone X");
}

编辑 2:

我不认为我的问题是链接问题的重复。当然,有一些方法可以“测量”当前设备的不同属性,并使用结果来决定使用哪个设备。但是,这不是我的问题的实际意义,因为我在第一次编辑中试图强调。

实际的问题是:“是否可以直接检测当前设备是否为 iPhone X(例如通过某些 SDK 功能)还是我必须使用间接测量”

根据到目前为止给出的答案,我假设答案是“不,没有直接的方法。测量是要走的路”。

最佳答案

根据您的问题,答案是否定的。没有直接的方法。如需更多信息,您可以在此处获取信息:

  • How to get device make and model on iOS?

  • how to check screen size of iphone 4 and iphone 5 programmatically in swift

iPhone X 高度为 2436 像素

来自 Device Screen Sizes and resolutions :

来自 Device Screen Sizes and Orientations :

Swift 3 及更高版本:

if UIDevice().userInterfaceIdiom == .phone {
    switch UIScreen.main.nativeBounds.height {
        case 1136:
            print("iPhone 5 or 5S or 5C")
        
        case 1334:
            print("iPhone 6/6S/7/8")
        
        case 1920, 2208:
            print("iPhone 6+/6S+/7+/8+")
        
        case 2436:
            print("iPhone X/XS/11 Pro")
        
        case 2688:
            print("iPhone XS Max/11 Pro Max")
        
        case 1792:
            print("iPhone XR/ 11 ")
        
        default:
            print("Unknown")
        }
    }

Objective-C:

if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        switch ((int)[[UIScreen mainScreen] nativeBounds].size.height) {
            case 1136:
                printf("iPhone 5 or 5S or 5C");
                    break;

            case 1334:
                printf("iPhone 6/6S/7/8");
                break;

            case 1920:
            case 2208:
                printf("iPhone 6+/6S+/7+/8+");
                break;

           case 2436:
                printf("iPhone X/XS/11 Pro");
                 break;

            case 2688:
                printf("iPhone XS Max/11 Pro Max");
                 break;

            case 1792:
                printf("iPhone XR/ 11 ");
                 break;

            default:
                printf("Unknown");
                break;
        }
    }

Xamarin.iOS:

if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone) {
    if ((UIScreen.MainScreen.Bounds.Height * UIScreen.MainScreen.Scale) == 1136) {
        Console.WriteLine("iPhone 5 or 5S or 5C");
    } else if ((UIScreen.MainScreen.Bounds.Height * UIScreen.MainScreen.Scale) == 1334) {
        Console.WriteLine("iPhone 6/6S/7/8");
    } else if ((UIScreen.MainScreen.Bounds.Height * UIScreen.MainScreen.Scale) == 1920 || (UIScreen.MainScreen.Bounds.Height * UIScreen.MainScreen.Scale) == 2208) {
        Console.WriteLine("iPhone 6+/6S+/7+/8+");
    } else if ((UIScreen.MainScreen.Bounds.Height * UIScreen.MainScreen.Scale) == 2436) {
        Console.WriteLine("iPhone X, XS, 11 Pro");
    } else if ((UIScreen.MainScreen.Bounds.Height * UIScreen.MainScreen.Scale) == 2688) {
        Console.WriteLine("iPhone XS Max, 11 Pro Max");
    } else if ((UIScreen.MainScreen.Bounds.Height * UIScreen.MainScreen.Scale) == 1792) {
        Console.WriteLine("iPhone XR, 11");
    } else {
        Console.WriteLine("Unknown");
    }
}

根据您的问题如下:

或者使用 screenSize.height 作为 float 812.0f 而不是 int 812

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
    CGSize screenSize = [[UIScreen mainScreen] bounds].size;
        // 812.0 on iPhone X, XS
        // 896.0 on iPhone XS Max, XR.

    if (screenSize.height >= 812.0f)
        NSLog(@"iPhone X");
    }

有关更多信息,您可以引用 iOS 人机界面指南中的以下页面:

  • Adaptivity and Layout - Visual Design - iOS - Human Interface Guidelines

swift :

topNotch 检测:

If anyone considering using notch to detect iPhoneX, mind that on "landscape" its same for all iPhones.

var hasTopNotch: Bool {
    if #available(iOS 13.0,  *) {
        return UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.safeAreaInsets.top ?? 0 > 20
    }else{
     return UIApplication.shared.delegate?.window??.safeAreaInsets.top ?? 0 > 20
    }

    return false
}

Objective-C:

- (BOOL)hasTopNotch {
   if (@available(iOS 13.0, *)) {
       return [self keyWindow].safeAreaInsets.top > 20.0;
   }else{
       return [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top > 20.0;
   }
   return  NO;
}

- (UIWindow*)keyWindow {
    UIWindow        *foundWindow = nil;
    NSArray         *windows = [[UIApplication sharedApplication]windows];
    for (UIWindow   *window in windows) {
        if (window.isKeyWindow) {
            foundWindow = window;
            break;
        }
    }
    return foundWindow;
}

更新:

不要使用 userInterfaceIdiom 属性来识别设备类型,如 documentation for userInterfaceIdiom解释:

For universal applications, you can use this property to tailor the behavior of your application for a specific type of device. For example, iPhone and iPad devices have different screen sizes, so you might want to create different views and controls based on the type of the current device.

也就是说,这个属性只是用来标识正在运行的应用的 View 样式。但是,iPhone 应用(不是通用的)可以通过 App Store 安装在 iPad 设备上,在这种情况下,userInterfaceIdiom 也会返回 UIUserInterfaceIdiomPhone

正确的方法是通过uname获取机器名。详情请查看以下内容:

  • How to get device make and model on iOS?

https://stackoverflow.com/questions/46192280/

相关文章:

objective-c - Xcode 6 中未创建 Swift 到 Objective-C hea

ios - Pod 安装停留在 "Setting up CocoaPods Master repo"

ios - 单个 UILabel 中的粗体和非粗体文本?

ios - 如何在 iOS 上找到最顶层的 View Controller

iphone - 如何比较两个 NSDates : Which is more recent?

ios - UIView无限360度旋转动画?

ios - Objective-C 中的自动引用计数不能防止或最小化什么样的泄漏?

iOS - 从 ViewController 调用 App Delegate 方法

iphone - 如何使用使用 Interface Builder 创建的 nib 文件加载 UIV

objective-c - 为设备编译时出现 Apple Mach-O 链接器错误