使用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获得。