使用Swift中的UI_USER_INTERFACE_IDIOM()检测当前设备

在iPhone和iPad之间,Swift中的UI_USER_INTERFACE_IDIOM()相当于什么?

在Swift中编译时,我得到了Use of unresolved identifier错误。

在使用Swift时,可以使用enum UIUserInterfaceIdiom ,定义如下:

 enum UIUserInterfaceIdiom : Int { case unspecified case phone // iPhone and iPod touch style UI case pad // iPad style UI } 

所以你可以使用它:

 UIDevice.current.userInterfaceIdiom == .pad UIDevice.current.userInterfaceIdiom == .phone UIDevice.current.userInterfaceIdiom == .unspecified 

或者用一个Switch语句:

  switch UIDevice.current.userInterfaceIdiom { case .phone: // It's an iPhone case .pad: // It's an iPad case .unspecified: // Uh, oh! What could it be? } 

UI_USER_INTERFACE_IDIOM()是一个Objective-Cmacros,其定义如下:

 #define UI_USER_INTERFACE_IDIOM() \ ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? \ [[UIDevice currentDevice] userInterfaceIdiom] : \ UIUserInterfaceIdiomPhone) 

另外,请注意,即使在使用Objective-C时, UI_USER_INTERFACE_IDIOM()macros也只在定位iOS 3.2及更低版本时才需要。 部署到iOS 3.2或更高版本时,可以直接使用[UIDevice userInterfaceIdiom]

你应该使用这个GBDeviceInfo框架或…

苹果定义这个:

 public enum UIUserInterfaceIdiom : Int { case unspecified case phone // iPhone and iPod touch style UI case pad // iPad style UI @available(iOS 9.0, *) case tv // Apple TV style UI @available(iOS 9.0, *) case carPlay // CarPlay style UI } 

所以对于严格定义的设备可以使用这个代码

 struct ScreenSize { static let SCREEN_WIDTH = UIScreen.main.bounds.size.width static let SCREEN_HEIGHT = UIScreen.main.bounds.size.height static let SCREEN_MAX_LENGTH = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT) static let SCREEN_MIN_LENGTH = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT) } struct DeviceType { static let IS_IPHONE_4_OR_LESS = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0 static let IS_IPHONE_5 = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0 static let IS_IPHONE_6_7 = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0 static let IS_IPHONE_6P_7P = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0 static let IS_IPAD = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0 static let IS_IPAD_PRO = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0 } 

如何使用

 if DeviceType.IS_IPHONE_6P_7P { print("IS_IPHONE_6P_7P") } 

检测iOS版本

 struct Version{ static let SYS_VERSION_FLOAT = (UIDevice.current.systemVersion as NSString).floatValue static let iOS7 = (Version.SYS_VERSION_FLOAT < 8.0 && Version.SYS_VERSION_FLOAT >= 7.0) static let iOS8 = (Version.SYS_VERSION_FLOAT >= 8.0 && Version.SYS_VERSION_FLOAT < 9.0) static let iOS9 = (Version.SYS_VERSION_FLOAT >= 9.0 && Version.SYS_VERSION_FLOAT < 10.0) } 

如何使用

 if Version.iOS8 { print("iOS8") } 

Swift 2.0和iOS 9&Xcode 7.1

 // 1. request an UITraitCollection instance let deviceIdiom = UIScreen.mainScreen().traitCollection.userInterfaceIdiom // 2. check the idiom switch (deviceIdiom) { case .Pad: print("iPad style UI") case .Phone: print("iPhone and iPod touch style UI") case .TV: print("tvOS style UI") default: print("Unspecified UI idiom") } 

Swift 3.0

 // 1. request an UITraitCollection instance let deviceIdiom = UIScreen.main.traitCollection.userInterfaceIdiom // 2. check the idiom switch (deviceIdiom) { case .pad: print("iPad style UI") case .phone: print("iPhone and iPod touch style UI") case .tv: print("tvOS style UI") default: print("Unspecified UI idiom") } 

使用UITraitCollection。 iOS trait环境通过UITraitEnvironment协议的traitCollection属性公开。 该协议被以下类别采用:

  • UIScreen
  • 的UIWindow
  • 的UIViewController
  • UIPresentationController
  • 的UIView

if / else情况:

  if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad) { // Ipad } else { // Iphone } 

Swift 2.x:

添加到Beslav Turalov答案的新条目iPad Pro可以很容易地find这条线

检测iPad Pro

 struct DeviceType { ... static let IS_IPAD_PRO = UIDevice.currentDevice().userInterfaceIdiom == .Pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0 } 

斯威夫特3(电视和汽车添加):

 struct ScreenSize { static let SCREEN_WIDTH = UIScreen.main.bounds.size.width static let SCREEN_HEIGHT = UIScreen.main.bounds.size.height static let SCREEN_MAX_LENGTH = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT) static let SCREEN_MIN_LENGTH = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT) } struct DeviceType { static let IS_IPHONE = UIDevice.current.userInterfaceIdiom == .phone static let IS_IPHONE_4_OR_LESS = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0 static let IS_IPHONE_5 = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0 static let IS_IPHONE_6 = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0 static let IS_IPHONE_6P = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0 static let IS_IPHONE_7 = IS_IPHONE_6 static let IS_IPHONE_7P = IS_IPHONE_6P static let IS_IPAD = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0 static let IS_IPAD_PRO_9_7 = IS_IPAD static let IS_IPAD_PRO_12_9 = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0 static let IS_TV = UIDevice.current.userInterfaceIdiom == .tv static let IS_CAR_PLAY = UIDevice.current.userInterfaceIdiom == .carPlay } struct Version{ static let SYS_VERSION_FLOAT = (UIDevice.current.systemVersion as NSString).floatValue static let iOS7 = (Version.SYS_VERSION_FLOAT < 8.0 && Version.SYS_VERSION_FLOAT >= 7.0) static let iOS8 = (Version.SYS_VERSION_FLOAT >= 8.0 && Version.SYS_VERSION_FLOAT < 9.0) static let iOS9 = (Version.SYS_VERSION_FLOAT >= 9.0 && Version.SYS_VERSION_FLOAT < 10.0) static let iOS10 = (Version.SYS_VERSION_FLOAT >= 10.0 && Version.SYS_VERSION_FLOAT < 11.0) } 

用法

 if DeviceType.IS_IPHONE_7P { print("iPhone 7 plus") } if DeviceType.IS_IPAD_PRO_9_7 && Version.iOS10 { print("iPad pro 9.7 with iOS 10 version") } 

我这样做:

 UIDevice.current.model 

它显示设备的名称。

要检查是否是iPad或iPhone:

 if ( UIDevice.current.model.range(of: "iPad") != nil){ print("I AM IPAD") } else { print("I AM IPHONE") } 

尝试添加一个像这样的扩展名:

  public 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 where value != 0 else { return identifier } return identifier + String(UnicodeScalar(UInt8(value))) } switch identifier { case "iPod5,1": return "iPod Touch 5" case "iPod7,1": return "iPod Touch 6" case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4" case "iPhone4,1": return "iPhone 4s" case "iPhone5,1", "iPhone5,2": return "iPhone 5" case "iPhone5,3", "iPhone5,4": return "iPhone 5c" case "iPhone6,1", "iPhone6,2": return "iPhone 5s" case "iPhone7,2": return "iPhone 6" case "iPhone7,1": return "iPhone 6 Plus" case "iPhone8,1": return "iPhone 6s" case "iPhone8,2": return "iPhone 6s Plus" case "iPhone9,1", "iPhone9,3": return "iPhone 7" case "iPhone9,2", "iPhone9,4": return "iPhone 7 Plus" case "iPhone8,4": return "iPhone SE" case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":return "iPad 2" case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad 3" case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad 4" case "iPad4,1", "iPad4,2", "iPad4,3": return "iPad Air" case "iPad5,3", "iPad5,4": return "iPad Air 2" case "iPad2,5", "iPad2,6", "iPad2,7": return "iPad Mini" case "iPad4,4", "iPad4,5", "iPad4,6": return "iPad Mini 2" case "iPad4,7", "iPad4,8", "iPad4,9": return "iPad Mini 3" case "iPad5,1", "iPad5,2": return "iPad Mini 4" case "iPad6,3", "iPad6,4", "iPad6,7", "iPad6,8":return "iPad Pro" case "AppleTV5,3": return "Apple TV" case "i386", "x86_64": return "Simulator" default: return identifier } } } 

这是你将如何使用它:

 let modelName = UIDevice.currentDevice().modelName 

编辑对于模拟器,你可以在这里尝试一个解决scheme

Swift 2.0和iOS 7+ / iOS 8+ / iOS 9+

 public class Helper { public class var isIpad:Bool { if #available(iOS 8.0, *) { return UIScreen.mainScreen().traitCollection.userInterfaceIdiom == .Pad } else { return UIDevice.currentDevice().userInterfaceIdiom == .Pad } } public class var isIphone:Bool { if #available(iOS 8.0, *) { return UIScreen.mainScreen().traitCollection.userInterfaceIdiom == .Phone } else { return UIDevice.currentDevice().userInterfaceIdiom == .Phone } } } 

使用 :

 if Helper.isIpad { } 

要么

 guard Helper.isIpad else { return } 

谢谢@ user3378170

仅供参考,我已经使用UI_USER_INTERFACE_IDIOM()为我的应用程序写在Swift中。 该应用程序可以很好地编译与XCode 6.3.1没有任何警告该命令,运行良好的模拟器(与任何选定的设备),并在所有我的真实设备(iPhone,iPad)的iOS版本从7.1到8.3。

然而,该应用程序在苹果的评论者的设备上坠毁(并被拒绝)。 这花了我几天的时间来检测问题,只需重新上传到iTunes Connect。

现在我使用UIDevice.currentDevice().userInterfaceIdiom而我的应用程序可以从这种崩溃中生存下来。

Swift 3.0

 let userInterface = UIDevice.current.userInterfaceIdiom if(userInterface == .pad){ //iPads }else if(userInterface == .phone){ //iPhone }else if(userInterface == .carPlay){ //CarPlay }else if(userInterface == .tv){ //AppleTV } 

如果你想检查当前的设备是否它的iPad或iPhone,那么你可以使用这些代码行:

  if(UIDevice.currentDevice().userInterfaceIdiom == .Pad){ }else if(UIDevice.currentDevice().userInterfaceIdiom == .Phone){ } 

对上面的答案做了一些补充,以便返回一个types而不是string值。

我想这主要是用于UI调整,所以我不认为它包括所有的子模型,即iPhone 5s相关,但这可以很容易地扩展到模型testing的isDevicearrays

testing在Swift 3.1 Xcode 8.3.2中使用物理和仿真器设备

执行:

UIDevice.whichDevice()

 public enum SVNDevice { case isiPhone4, isIphone5, isIphone6or7, isIphone6por7p, isIphone, isIpad, isIpadPro } extension UIDevice { class func whichDevice() -> SVNDevice? { let isDevice = { (comparision: Array<(Bool, SVNDevice)>) -> SVNDevice? in var device: SVNDevice? comparision.forEach({ device = $0.0 ? $0.1 : device }) return device } return isDevice([ (UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0, SVNDevice.isiPhone4), (UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0, SVNDevice.isIphone5), (UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0, SVNDevice.isIphone6or7), (UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0, SVNDevice.isIphone6por7p), (UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0, SVNDevice.isIpad), (UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0, SVNDevice.isIpadPro)]) } } private struct ScreenSize { static let SCREEN_WIDTH = UIScreen.main.bounds.size.width static let SCREEN_HEIGHT = UIScreen.main.bounds.size.height static let SCREEN_MAX_LENGTH = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT) static let SCREEN_MIN_LENGTH = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT) } 

我创build了一个名为SVNBootstaper的框架,其中包括这个和其他一些帮助协议,它是公开的,可以通过Carthage获得。