ios - 检测设备是否为 iPhone X

标签 ios objective-c iphone 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 功能)还是我必须使用间接测量”

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

最佳答案

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

iPhone X 高度为 2436 像素

来自 Device Screen Sizes and resolutions :

enter image description here

来自 Device Screen Sizes and Orientations :

enter image description here

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 人机界面指南中的以下页面:

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获取机器名。详情请查看以下内容:

关于ios - 检测设备是否为 iPhone X,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46192280/

相关文章:

ios - 如何以编程方式将不同单元格的不同图像添加到 tableView (Swift 3)

c# - 获取 UIView 的大小

xcode - iOS SDK 4.1 中的 1347 错误

iOS - 将单元格添加到带有核心数据和 NSFetchedResultsController 的空 UITableView 部分

objective-c - 如何更改scrollWheel : handler into a magnifyWithEvent: call?

iphone - 可以更改个人 Apple 开发者帐户的发布者/版权名称吗?

ios - 今天小部件中的 UIButton 不调用连接的 IBAction 并且不显示图像

ios - willSelectRowAtIndexPath 不改变 detailTextLabel

iphone - 所有设备的应用商店屏幕截图尺寸

iphone - iOS中如何访问需要认证的URL