我的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功能),还是我必须使用间接测量?”
根据目前给出的答案,我假设答案是“不,没有直接的方法。测量是要走的路。”
我正在使用Peter Kreinz的代码(因为它是干净的,做了我需要的),但后来我意识到它只在设备是纵向的时候工作(因为顶部填充将在顶部,显然)
所以我创建了一个扩展来处理所有的方向与它各自的填充,而不依赖于屏幕大小:
extension UIDevice {
var isIphoneX: Bool {
if #available(iOS 11.0, *), isIphone {
if isLandscape {
if let leftPadding = UIApplication.shared.keyWindow?.safeAreaInsets.left, leftPadding > 0 {
return true
}
if let rightPadding = UIApplication.shared.keyWindow?.safeAreaInsets.right, rightPadding > 0 {
return true
}
} else {
if let topPadding = UIApplication.shared.keyWindow?.safeAreaInsets.top, topPadding > 0 {
return true
}
if let bottomPadding = UIApplication.shared.keyWindow?.safeAreaInsets.bottom, bottomPadding > 0 {
return true
}
}
}
return false
}
var isLandscape: Bool {
return UIDeviceOrientationIsLandscape(orientation) || UIInterfaceOrientationIsLandscape(UIApplication.shared.statusBarOrientation)
}
var isPortrait: Bool {
return UIDeviceOrientationIsPortrait(orientation) || UIInterfaceOrientationIsPortrait(UIApplication.shared.statusBarOrientation)
}
var isIphone: Bool {
return self.userInterfaceIdiom == .phone
}
var isIpad: Bool {
return self.userInterfaceIdiom == .pad
}
}
在你的电话网站上
let res = UIDevice.current.isIphoneX
我最近不得不解决同样的问题。虽然这个问题得到了明确的答案(“否”),但这可能会帮助其他需要iPhone X特定布局行为的人。
我对这款设备是不是iPhone x并不感兴趣,我感兴趣的是它的显示屏是否有凹槽。
private static var hasNotchedDisplay: Bool {
if let window = UIApplication.shared.keyWindow {
return (window.compatibleSafeAreaInsets.top > 20.0 || window.compatibleSafeAreaInsets.left > 0.0 || window.compatibleSafeAreaInsets.right > 0.0)
}
return false
}
您还可以沿着相同的行编写hasOnScreenHomeIndicator变量(尽管检查底部安全区域,也许?)
上面使用了我在UIView上的扩展,方便地访问iOS 10和更早的安全区域嵌入。
@objc public extension UIView {
@objc public var compatibleSafeAreaInsets: UIEdgeInsets {
if #available(iOS 11.0, *) {
return safeAreaInsets
} else {
return .zero
}
}
@objc public var compatibleSafeAreaLayoutGuide: UILayoutGuide {
if #available(iOS 11.0, *) {
return safeAreaLayoutGuide
} else {
return layoutMarginsGuide
}
}
}
随着iOS 12的发布,像iPhone X这样的设备可能会被归入这一类别。
`
extension UIDevice {
var isPortrait: Bool {
return UIDeviceOrientationIsPortrait(orientation) ||
UIInterfaceOrientationIsPortrait(UIApplication.shared.statusBarOrientation)
}
var isDeviceWith_XShape : Bool {
if self.userInterfaceIdiom == .phone {
if isPortrait
{
switch UIScreen.main.nativeBounds.height {
case 2436,2688,1792:
print("iPhone X, Xs, Xr, Xs Max")
return true
default:
print("Any other device")
return false
}
}
else
{
switch UIScreen.main.nativeBounds.width {
case 2436,2688,1792:
print("iPhone X, Xs, Xr, Xs Max")
return true
default:
print("Any other device")
return false
}
}
}
else
{
return false
}
}`
你可以这样做,根据尺寸检测iPhone X设备。
斯威夫特
if UIDevice().userInterfaceIdiom == .phone && UIScreen.main.nativeBounds.height == 2436 {
//iPhone X
}
目标- C
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone && UIScreen.mainScreen.nativeBounds.size.height == 2436) {
//iPhone X
}
But,
这是不够的。如果苹果发布的下一代iPhone与iPhone x的尺寸相同,那么最好的方法是使用硬件字符串来检测设备。
对于较新的设备硬件字符串如下。
iPhone 8 - iphone10,1或iPhone 10,4
iPhone 8 Plus - iPhone10,2或iPhone10, 5
iPhone X - iPhone10,3或iPhone10,6
我认为苹果不希望我们手动检查设备是否有“notch”或“home indicator”,但有效的代码是:
-(BOOL)hasTopNotch{
if (@available(iOS 11.0, *)) {
float max_safe_area_inset = MAX(MAX([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top, [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.right),MAX([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.bottom, [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.left));
return max_safe_area_inset >= 44.0;
}
return NO;
}
-(BOOL)hasHomeIndicator{
if (@available(iOS 11.0, *)) {
int iNumberSafeInsetsEqualZero = 0;
if([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top == 0.0)iNumberSafeInsetsEqualZero++;
if([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.right == 0.0)iNumberSafeInsetsEqualZero++;
if([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.bottom == 0.0)iNumberSafeInsetsEqualZero++;
if([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.left == 0.0)iNumberSafeInsetsEqualZero++;
return iNumberSafeInsetsEqualZero <= 2;
}
return NO;
}
其他一些帖子都没用。例如,竖屏模式下“通话状态栏”(绿色栏)的iPhone 6S就有一个很大的顶部安全插件。在我的代码中,所有的情况都被占用(即使设备以纵向或横向启动)