我的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功能),还是我必须使用间接测量?”
根据目前给出的答案,我假设答案是“不,没有直接的方法。测量是要走的路。”
另一种可能是,在iOS 11和iOS 12上都能运行,因为iPhone X是唯一一款顶部有凹槽、嵌框为44的手机。这就是我在这里真正发现的:
objective - c:
BOOL iPhoneX = NO;
if (@available(iOS 11.0, *)) {
UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
if (mainWindow.safeAreaInsets.top > 24.0) {
iPhoneX = YES;
}
}
斯威夫特4:
/// 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
}
当然,如果你是在横向,你可能需要检查左右安全区域的嵌入。
Edit: _window是AppDelegate的UIWindow,这个检查在应用didFinishLaunchingWithOptions中完成。
iOS 12的答案更新,以检查顶部>是否为24,而不是顶部> 0。
编辑:在模拟器中,您可以选择硬件,切换通话状态栏。这样做表明,在通话时,iOS 11的iPhone X或iOS 12的iPhone XS上的状态栏高度没有变化。在这两种情况下,改变的只是时间图标,它的背景都是绿色的。这是一张快照:
我知道这只是一个快速的解决方案,但它可以帮助一些人。
我在每个项目中都有global .swift,有一些代码来简化我的生活,我总是添加的一件事是ScreenSize和hasNotch,可以轻松检测手机类型和尺寸:
struct ScreenSize {
static let width = UIScreen.main.bounds.size.width
static let height = UIScreen.main.bounds.size.height
}
var hasNotch: Bool {
return UIApplication.shared.delegate?.window??.safeAreaInsets.top ?? 0 > 0
}
然后使用它:
if hasNotch {
print("This executes on all phones with a notch")
}
使用简单的方法检测任何设备。像下面,
func isPhoneDevice() -> Bool {
return UIDevice.current.userInterfaceIdiom == .phone
}
func isDeviceIPad() -> Bool {
return UIDevice.current.userInterfaceIdiom == .pad
}
func isPadProDevice() -> Bool {
let SCREEN_WIDTH: CGFloat = UIScreen.main.bounds.size.width
let SCREEN_HEIGHT: CGFloat = UIScreen.main.bounds.size.height
let SCREEN_MAX_LENGTH: CGFloat = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
return UIDevice.current.userInterfaceIdiom == .pad && SCREEN_MAX_LENGTH == 1366.0
}
func isPhoneXandXSDevice() -> Bool {
let SCREEN_WIDTH = CGFloat(UIScreen.main.bounds.size.width)
let SCREEN_HEIGHT = CGFloat(UIScreen.main.bounds.size.height)
let SCREEN_MAX_LENGTH: CGFloat = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
return UIDevice.current.userInterfaceIdiom == .phone && SCREEN_MAX_LENGTH == 812.0
}
func isPhoneXSMaxandXRDevice() -> Bool {
let SCREEN_WIDTH = CGFloat(UIScreen.main.bounds.size.width)
let SCREEN_HEIGHT = CGFloat(UIScreen.main.bounds.size.height)
let SCREEN_MAX_LENGTH: CGFloat = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
return UIDevice.current.userInterfaceIdiom == .phone && SCREEN_MAX_LENGTH == 896.0
}
像这样叫,
if isPhoneDevice() {
// Your code
}
SWIFT 4/5可重用扩展,支持iPhone 12
extension UIDevice {
enum `Type` {
case iPhone_5_5S_5C_SE1
case iPhone_6_6S_7_8_SE2
case iPhone_6_6S_7_8_PLUS
case iPhone_X_XS_12mini
case iPhone_XR_11
case iPhone_XS_11Pro_Max
case iPhone_12_Pro
case iPhone_12_Pro_Max
}
var hasHomeButton: Bool {
switch type {
case . iPhone_X_XS_12mini, . iPhone_XR_11, .iPhone_XS_11Pro_Max, . iPhone_XS_11Pro_Max, .iPhone_12_Pro, .iPhone_12_Pro_Max:
return false
default:
return true
}
}
var type: Type {
if UI_USER_INTERFACE_IDIOM() == .phone {
switch UIScreen.main.nativeBounds.height {
case 1136:
return .iPhone_5_5S_5C_SE1
case 1334:
return .iPhone_6_6S_7_8_SE2
case 1920, 2208:
return .iPhone_6_6S_7_8_PLUS
case 2436:
return .iPhone_X_XS_12mini
case 2532:
return .iPhone_12_Pro
case 2688:
return .iPhone_XS_11Pro_Max
case 2778:
return .iPhone_12_Pro_Max
case 1792:
return .iPhone_XR_11
default:
assertionFailure("Unknown phone device detected!")
return .iPhone_6_6S_7_8_SE2
}
} else {
assertionFailure("Unknown idiom device detected!")
return .iPhone_6_6S_7_8_SE2
}
}
}