ios 检测设备是否为 iPhone X

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46192280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:26:40  来源:igfitidea点击:

Detect if the device is iPhone X

iosobjective-ciphoneiphone-x

提问by Andrei Herford

My iOS app uses a custom height for the UINavigationBarwhich leads to some problems on the new iPhone X.

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

Does someone already know how to reliabledetect programmatically (in Objective-C) if an app is running on iPhone X?

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

EDIT:

编辑:

Of course checking the size of the screen is possible, however, I wonder if there is some "build in" method like TARGET_OS_IPHONEto detect iOS...

当然可以检查屏幕的大小,但是,我想知道是否有一些“内置”方法,例如TARGET_OS_IPHONE检测 iOS...

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

EDIT 2:

编辑2:

I do not think, that my question is a duplicate of the linked question. Of course, there are methods to "measure" different properties of the current device and to use the results to decide which device is used. However, this was not the actual point of my question as I tried to emphasize in my first edit.

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

The actual question is: "Is it possible to directly detect if the current device is an iPhone X (e.g. by some SDK feature) or do I have to use indirect measurements"?

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

By the answers given so far, I assume that the answer is "No, there is no direct methods. Measurements are the way to go".

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

回答by Anbu.Karthik

Based on your question, the answer is no. There are no direct methods. For more information you can get the information here:

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

and

The iPhone X height is 2436 px

iPhone X 高度为 2436 像素

From Device Screen Sizes and resolutions:

设备屏幕尺寸和分辨率

enter image description here

在此处输入图片说明

From Device Screen Sizes and Orientations:

设备屏幕尺寸和方向

enter image description here

在此处输入图片说明

Swift 3 and later:

斯威夫特 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:

目标-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, 2208:
            printf("iPhone 6+/6S+/7+/8+");
            break;

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

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

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

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

Xamarin.iOS:

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");
    }
}

Based on your question as follow:

根据您的问题如下:

Or use screenSize.heightas float 812.0fnot int 812.

screenSize.height用作 float812.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");
    }

For more information you can refer the following page in iOS Human Interface Guidelines:

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

Swift:

斯威夫特

Detect with topNotch:

检测topNotch

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

如果有人考虑使用缺口来检测 iPhoneX,请注意“横向”对于所有 iPhone 都是一样的。

var hasTopNotch: Bool {
    if #available(iOS 13.0,  *) {
        return UIApplication.shared.windows.filter {
- (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;
}
.isKeyWindow}.first?.safeAreaInsets.top ?? 0 > 20 }else{ return UIApplication.shared.delegate?.window??.safeAreaInsets.top ?? 0 > 20 } return false }

Objective-C:

目标-C

    BOOL iPhoneX = NO;
    if (@available(iOS 11.0, *)) {
        UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
        if (mainWindow.safeAreaInsets.top > 24.0) {
            iPhoneX = YES;
        }
    }

UPDATE:

更新

Do not use the userInterfaceIdiomproperty to identify the device type, as the documentation for userInterfaceIdiomexplains:

请勿使用该userInterfaceIdiom属性来识别设备类型,如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.

对于通用应用程序,您可以使用此属性为特定类型的设备定制应用程序的行为。例如,iPhone 和 iPad 设备具有不同的屏幕尺寸,因此您可能希望根据当前设备的类型创建不同的视图和控件。

That is, this property is just used to identify the running app's view style. However, the iPhone app (not the universal) could be installed in iPad device via App store, in that case, the userInterfaceIdiomwill return the UIUserInterfaceIdiomPhone, too.

也就是说,这个属性只是用来标识正在运行的应用程序的视图样式。但是,iPhone 应用程序(非通用)可以通过 App Store 安装在 iPad 设备中,在这种情况下,userInterfaceIdiom也将返回UIUserInterfaceIdiomPhone.

The right way is to get the machine name via uname. Check the following for details:

正确的方法是通过uname. 检查以下详细信息:

回答by saswanb

Another possibility, which works on iOS 11 and iOS 12 because the iPhone X is the only one with a notch at the top and an inset of 44. That is what I am really detecting here:

另一种可能性,它适用于 iOS 11 和 iOS 12,因为 iPhone X 是唯一一个顶部有凹口且插入 44 的。这就是我在这里真正检测到的:

Objective-C:

目标-C:

/// Has safe area
///
/// with notch: 44.0 on iPhone X, XS, XS Max, XR.
///
/// without notch: 20.0 on iPhone 8 on iOS 12+.
///
static var hasSafeArea: Bool {
    guard #available(iOS 11.0, *), let topPadding = UIApplication.shared.keyWindow?.safeAreaInsets.top, topPadding > 24 else {
        return false
    }
    return true
}

Swift 4:

斯威夫特 4:

class var hasTopNotch: Bool {
    if #available(iOS 11.0, tvOS 11.0, *) {
        // with notch: 44.0 on iPhone X, XS, XS Max, XR.
        // without notch: 24.0 on iPad Pro 12.9" 3rd generation, 20.0 on iPhone 8 on iOS 12+.
        return UIApplication.shared.delegate?.window??.safeAreaInsets.top ?? 0 > 24
    }
    return false
}

And of course, you might need to check the left and right safe area insets if you are in landscape orientation.

当然,如果您处于横向,您可能需要检查左右安全区域插图。

Edit: _window is the UIWindow of the AppDelegate, where this check is done in application didFinishLaunchingWithOptions.

编辑:_window 是 AppDelegate 的 UIWindow,这里检查在应用程序 didFinishLaunchingWithOptions 中完成。

Answer updated for iOS 12 to check if top > 24 rather than top > 0.

针对 iOS 12 更新的答案以检查是否 top > 24 而不是 top > 0。

Edit: In the simulator you can go to Hardware, Toggle In-call Status Bar. Doing that shows me that the status bar height does not change on iPhone X on iOS 11 or iPhone XS iOS 12 when engaged in a call. All that changes is the time icon, which gets a green background, in both cases. Here's a snap:

编辑:在模拟器中,您可以转到硬件,切换通话状态栏。这样做向我表明,在进行通话时,iOS 11 上的 iPhone X 或 iPhone XS iOS 12 上的状态栏高度不会改变。所有改变的是时间图标,在这两种情况下,它的背景都是绿色的。这是一个快照:

enter image description here

在此处输入图片说明

回答by C?ur

You shall perform different detections of iPhone X depending on the actual need.

您应根据实际需要对 iPhone X 进行不同的检测。

for dealing with the top notch (statusbar, navbar), etc.

用于处理一流的(状态栏、导航栏)等。

class var hasBottomSafeAreaInsets: Bool {
    if #available(iOS 11.0, tvOS 11.0, *) {
        // with home indicator: 34.0 on iPhone X, XS, XS Max, XR.
        // with home indicator: 20.0 on iPad Pro 12.9" 3rd generation.
        return UIApplication.shared.delegate?.window??.safeAreaInsets.bottom ?? 0 > 0
    }
    return false
}

for dealing with the bottom home indicator (tabbar), etc.

用于处理底部主页指示器(tabbar)等。

class var isIphoneXOrBigger: Bool {
    // 812.0 on iPhone X, XS.
    // 896.0 on iPhone XS Max, XR.
    return UIScreen.main.bounds.height >= 812
}

for backgrounds size, fullscreen features, etc.

用于背景大小、全屏功能等。

class var isIphoneXOrLonger: Bool {
    // 812.0 / 375.0 on iPhone X, XS.
    // 896.0 / 414.0 on iPhone XS Max, XR.
    return UIScreen.main.bounds.height / UIScreen.main.bounds.width >= 896.0 / 414.0
}

Note: eventually mix it with UIDevice.current.userInterfaceIdiom == .phone
Note: this method requires to have a LaunchScreen storyboard or proper LaunchImages

注意:最终将它与UIDevice.current.userInterfaceIdiom == .phone
注意:此方法需要有一个 LaunchScreen 故事板或适当的 LaunchImages

for backgrounds ratio, scrolling features, etc.

用于背景比例、滚动功能等。

class var isIphoneX: Bool {
    var size = 0
    sysctlbyname("hw.machine", nil, &size, nil, 0)
    var machine = [CChar](repeating: 0, count: size)
    sysctlbyname("hw.machine", &machine, &size, nil, 0)
    let model = String(cString: machine)
    return model == "iPhone10,3" || model == "iPhone10,6"
}

Note: this method requires to have a LaunchScreen storyboard or proper LaunchImages

注意:此方法需要有 LaunchScreen 故事板或适当的 LaunchImages

for analytics, stats, tracking, etc.

用于分析、统计、跟踪等。

Get the machine identifier and compare it to documented values:

获取机器标识符并将其与记录的值进行比较:

class var isIphoneX: Bool {
    let model: String
    if TARGET_OS_SIMULATOR != 0 {
        model = ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] ?? ""
    } else {
        var size = 0
        sysctlbyname("hw.machine", nil, &size, nil, 0)
        var machine = [CChar](repeating: 0, count: size)
        sysctlbyname("hw.machine", &machine, &size, nil, 0)
        model = String(cString: machine)
    }
    return model == "iPhone10,3" || model == "iPhone10,6"
}

To include the simulator as a valid iPhone X in your analytics:

要将模拟器作为有效的 iPhone X 包含在您的分析中:

return model == "iPhone10,3" || model == "iPhone10,6" || model.starts(with: "iPhone11,")

To include iPhone XS, XS Max and XR, simply look for models starting with "iPhone11,":

要包括 iPhone XS、XS Max 和 XR,只需查找以“iPhone11”开头的型号:

import LocalAuthentication
/// will fail if user denies canEvaluatePolicy(_:error:)
class var canUseFaceID: Bool {
    if #available(iOS 11.0, *) {
        return LAContext().biometryType == .typeFaceID
    }
    return false
}

for faceID support

面部识别支持

if UIDevice().userInterfaceIdiom == .phone && UIScreen.main.nativeBounds.height == 2436 {
   //iPhone X
}

回答by Jaydeep

You can do like this to detect iPhone Xdevice according to dimension.

您可以这样做以根据尺寸检测iPhone X设备。

Swift

迅速

if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone && UIScreen.mainScreen.nativeBounds.size.height == 2436)  {
  //iPhone X     
}

Objective - C

目标-C

#import <sys/utsname.h>

NSString* deviceName()
{
    struct utsname systemInfo;
    uname(&systemInfo);

    return [NSString stringWithCString:systemInfo.machine
                          encoding:NSUTF8StringEncoding];
}

enter image description here

在此处输入图片说明

But,

但是

This is not sufficient way. What if Apple announced next iPhone with same dimension of iPhone X. so the best way is to use Hardware string to detect the device.

这还不够。如果苹果发布了与 iPhone X 相同尺寸的下一款 iPhone,那么最好的方法是使用硬件字符串来检测设备。

For newer device Hardware string is as below.

对于较新的设备硬件字符串如下。

iPhone 8 - iPhone10,1or iPhone 10,4

iPhone 8 - iPhone10,1iPhone 10,4

iPhone 8 Plus - iPhone10,2or iPhone 10,5

iPhone 8 Plus - iPhone10,2iPhone 10,5

iPhone X - iPhone10,3or iPhone10,6

iPhone X - iPhone10,3iPhone10,6

回答by Itachi

Check out the device model / machine name, DO NOT use the point/pixel count in your code directly, it's hard codeand meaningless for the device hardware, the device model is the only unique identifier for a type of device to match.

查看设备型号/机器名称,不要直接在代码中使用点/像素数,它是硬编码并且对设备硬件没有意义,设备型号是唯一匹配的设备类型的唯一标识符

@"iPhone10,3" on iPhone X (CDMA)
@"iPhone10,6" on iPhone X (GSM)

Result:

结果:

#import <sys/utsname.h>

NSString * GetDeviceModel(void)
{
    static dispatch_once_t onceToken;
    static NSString *strModelID = nil;

    dispatch_once(&onceToken, ^{
#if TARGET_IPHONE_SIMULATOR
        strModelID = NSProcessInfo.processInfo.environment[@"SIMULATOR_MODEL_IDENTIFIER"];
#else
        struct utsname systemInfo;

        uname(&systemInfo);
        strModelID = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
#endif
    });

    return strModelID;
}

// See the `Hardware strings` in https://en.wikipedia.org/wiki/List_of_iOS_devices
BOOL IsiPhoneX(void)
{
    NSString *strModelID = GetDeviceModel();

    return [strModelID isEqualToString:@"iPhone10,3"] || [strModelID isEqualToString:@"iPhone10,6"];
}

BOOL IsNotchiPhone(void)
{
    NSArray<NSString *> *notchiModels = @[
        @"iPhone10,3", @"iPhone10,6", // iPhone X
        @"iPhone11,2", @"iPhone11,4", @"iPhone11,6", // iPhone XS (Max)
        @"iPhone11,8", // iPhone XR
        @"iPhone12,1", @"iPhone12,3", @"iPhone12,5", // iPhone 11 (Pro (Max))
    ];

    return [notchiModels containsObject:GetDeviceModel()];
}

Refer to this answer.

参考这个答案

Full code implementation:

完整代码实现:

#define IS_IPHONE        (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_4      (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 480.0)
#define IS_IPHONE_5      (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
#define IS_IPHONE_6      (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
#define IS_IPHONE_6PLUS  (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_IPHONE_X      (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 812.0)

回答by Jagveer Singh

#define IS_IPHONE_XS      (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 812.0)
#define IS_IPHONE_X_MAX      (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 896.0)
#define IS_RETINA        ([[UIScreen mainScreen] scale] >= 2.0) // 3.0 for iPhone X, 2.0 for others

#define IS_IPAD_DEVICE   [(NSString*)[UIDevice currentDevice].model hasPrefix:@"iPad"]

define IS_IPHONE_X (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 812.0)

定义 IS_IPHONE_X (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 812.0)

extension UIDevice {
    static var isIphoneX: Bool {
        var modelIdentifier = ""
        if isSimulator {
            modelIdentifier = ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] ?? ""
        } else {
            var size = 0
            sysctlbyname("hw.machine", nil, &size, nil, 0)
            var machine = [CChar](repeating: 0, count: size)
            sysctlbyname("hw.machine", &machine, &size, nil, 0)
            modelIdentifier = String(cString: machine)
        }

        return modelIdentifier == "iPhone10,3" || modelIdentifier == "iPhone10,6"
    }

    static var isSimulator: Bool {
        return TARGET_OS_SIMULATOR != 0
    }
}

Note:- Be careful, it works fine only for portrait orientation

注意:- 请注意,它仅适用于纵向

回答by Cloud9999Strife

After looking at all the answers this is what I ended up doing:

在查看了所有答案后,这就是我最终要做的:

Solution (Swift 4.1 compatible)

解决方案(兼容 Swift 4.1)

if UIDevice.isIphoneX {
    // is iPhoneX
} else {
    // is not iPhoneX
}

Use

TARGET_OS_SIMULATOR != 0

Note

笔记

PreSwift 4.1 you can check if the app is running on a simulator like so:

Swift 4.1 之前,您可以检查应用程序是否在模拟器上运行,如下所示:

#if targetEnvironment(simulator)
    return true
#else
    return false
#endif

From Swift 4.1 and onwards you can check if the app is running on a simulator using the Target environment platform condition:

从 Swift 4.1 开始,您可以使用Target environment platform condition检查应用程序是否在模拟器上运行:

 let deviceType = UIDevice.current.modelName
        switch deviceType {
        case "iPhone10,3", "iPhone10,6":
            print("iPhoneX")
        case "iPhone11,2":
            print("iPhone XS")
        case "iPhone11,4":
            print("iPhone XS Max")
        case "iPhone11,6":
            print("iPhone XS Max China")
        case "iPhone11,8":
            print("iPhone XR")
        case "iPhone12,3":
            print("iPhone 11 Pro")
        case "iPhone12,5":
            print("iPhone 11 Pro Max")
        default:
            break
}

extension UIDevice {
    var modelName: String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
        return identifier
    }
}

(the older method will still work, but this new method is more future proof)

(旧方法仍然有效,但这种新方法更具前瞻性)

回答by clarus

All of these answers based on dimensions are susceptible to incorrect behavior on future devices. They'll work today, but what if there's an iPhone next year that's the same size but has the camera, etc. under the glass so there's no "notch?" If the only option is to update the app, then it's a poor solution for you and your customers.

所有这些基于维度的答案都容易受到未来设备上的错误行为的影响。他们今天可以工作,但如果明年有一部同样大小的 iPhone,但在玻璃下有相机等,所以没有“缺口”怎么办?如果唯一的选择是更新应用程序,那么这对您和您的客户来说都是一个糟糕的解决方案。

You can also check the hardware model string like "iPhone10,1", but that's problematic because sometimes Apple releases different model numbers for different carriers around the world.

您还可以检查硬件型号字符串,例如“iPhone10,1”,但这是有问题的,因为有时 Apple 会为世界各地的不同运营商发布不同的型号。

The correct approach is to redesign the top layout, or solve the problems you're having with the custom navigation bar height (that's what I'd focus on). But, if you decide not to do either of those things, realize that whatever you're doing is a hack to get this to work today, and you'll need to correct it at some point, perhaps multiple times, to keep the hacks working.

正确的方法是重新设计顶部布局,或者解决您在自定义导航栏高度方面遇到的问题(这是我关注的重点)。但是,如果您决定不做这些事情中的任何一件,请意识到您所做的任何事情都是为了让它在今天起作用,并且您需要在某个时候纠正它,可能需要多次纠正,以保留这些黑客在职的。

回答by Hyman

SWIFT 4+ Answer

SWIFT 4+ 答案

iPhone X, XR, XS, XSMAX, 11 Pro, 11 Pro Max:

iPhone X、XR、XS、XSMAX、11 Pro、11 Pro Max:

Note: Need real device for test

注:需要真机进行测试

Reference

参考

    public extension UIDevice {

    public enum `Type` {
        case iPad
        case iPhone_unknown
        case iPhone_5_5S_5C
        case iPhone_6_6S_7_8
        case iPhone_6_6S_7_8_PLUS
        case iPhone_X_Xs
        case iPhone_Xs_11_Pro_Max
        case iPhone_Xr_11
        case iPhone_11_Pro
    }

    public var hasHomeButton: Bool {
        switch type {
        case .iPhone_X_Xs, .iPhone_Xr_11, .iPhone_Xs_11_Pro_Max, .iPhone_11_Pro:
            return false
        default:
            return true
        }
    }

    public var type: Type {
        if userInterfaceIdiom == .phone {
            switch UIScreen.main.nativeBounds.height {
            case 1136: return .iPhone_5_5S_5C
            case 1334: return .iPhone_6_6S_7_8
            case 1920, 2208: return .iPhone_6_6S_7_8_PLUS
            case 2436: return .iPhone_X_Xs
            case 2688: return .iPhone_Xs_11_Pro_Max
            case 1792: return .iPhone_Xr_11
            case 2426: return .iPhone_11_Pro
            default: return .iPhone_unknown
        }
        }
        return .iPad
   }
}

回答by ale_stro

SWIFT 4/5reusable extensionwith iPhone 11support

SWIFT 4/5可重复使用的扩展iPhone 11支持

##代码##