我的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功能),还是我必须使用间接测量?”

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


当前回答

你不应该假设苹果发布的唯一具有不同UINavigationBar高度的设备将是iPhone x。尝试使用更通用的解决方案来解决这个问题。如果你想让条形图总是比默认高度大20px,你的代码应该为条形图的高度增加20px,而不是将其设置为64px (44px + 20px)。

其他回答

SWIFT 4+回答

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

注:需实物设备进行测试

参考

 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
    }
}

通常,程序员需要它来约束到顶部或底部,所以这些方法可以提供帮助

static func extraTop() -> CGFloat {

    var top: CGFloat = 0

    if #available(iOS 11.0, *) {

        if let t = UIApplication.shared.keyWindow?.safeAreaInsets.top {
            top = t
        }
    }
    return top
}

static func extraBottom() -> CGFloat {

    var bottom: CGFloat = 0

    if #available(iOS 11.0, *) {

        if let b = UIApplication.shared.keyWindow?.safeAreaInsets.bottom {
            bottom = b
        }
    }
    return bottom
}

在iPhone X之前,这些方法返回:0

iPhone X: 44和34

然后只需将这些额外的内容添加到顶部或底部约束

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

如何检测iOS设备型号和屏幕大小?

CheckDevice检测当前的设备型号和屏幕大小。

你也可以使用

CheckDevice.size () iPhone 12 mini的。screen5_4inch

等等…… 也许……

CheckDevice.isPhone ()

检查设备类型为iPhone。

CheckDevice isWatch()。

CheckDevice isSimulator()。

CheckDevice isPad()。

伟大的回购

CheckDevice https://github.com/ugurethemaydin/CheckDevice

对于那些获得2001px而不是2436px的原生边界高度的人(比如我),这是因为你使用的是iOS 11 (Xcode 8而不是Xcode 9)之前的旧SDK构建的应用程序。使用旧SDK, iOS将在iPhone X上显示应用程序的“黑盒子”,而不是将屏幕边缘扩展到顶部的“传感器缺口”。这减少了屏幕大小,这就是为什么该属性返回2001而不是2436。

如果您只对设备检测感兴趣,最简单的解决方案是检查两个大小。我使用这种方法来检测FaceID,同时使用一个旧的Xcode SDK,它没有ENUM值指定生物特征类型。在这种情况下,使用屏幕高度进行设备检测似乎是知道设备是否具有FaceID还是TouchID的最佳方法,而无需更新Xcode。