以点值检测iPhone 6/6 +屏幕尺寸

鉴于最新公布的iPhone 6 屏幕尺寸 :

iPhone 6: 1334h * 750w @2x (in points: 667h * 375w) iPhone 6+: 1920 * 1080 @3x (in points: 640h * 360w) 

我想知道是否有代码允许我检测用户设备的屏幕大小,以便我可以用用户的设备相应地调整UIImages和其他材料的大小。

到目前为止,我一直在使用以下内容:

 - (NSString *) platform{ size_t size; sysctlbyname("hw.machine", NULL, &size, NULL, 0); char *machine = malloc(size); sysctlbyname("hw.machine", machine, &size, NULL, 0); NSString *platform = [NSString stringWithUTF8String:machine]; free(machine); return platform; } - (NSString *) platformString{ NSString *platform = [self platform]; if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 1G"; if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G"; if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS"; if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4"; if ([platform isEqualToString:@"iPhone3,3"]) return @"Verizon iPhone 4"; if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S"; if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5 (GSM)"; if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (GSM+CDMA)"; if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (GSM)"; if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (GSM+CDMA)"; if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (GSM)"; if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (GSM+CDMA)"; if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G"; if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G"; if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G"; if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G"; if ([platform isEqualToString:@"iPod5,1"]) return @"iPod Touch 5G"; if ([platform isEqualToString:@"iPad1,1"]) return @"iPad"; if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)"; if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2 (GSM)"; if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)"; if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2 (WiFi)"; if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini (WiFi)"; if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini (GSM)"; if ([platform isEqualToString:@"iPad2,7"]) return @"iPad Mini (GSM+CDMA)"; if ([platform isEqualToString:@"iPad3,1"]) return @"iPad 3 (WiFi)"; if ([platform isEqualToString:@"iPad3,2"]) return @"iPad 3 (GSM+CDMA)"; if ([platform isEqualToString:@"iPad3,3"]) return @"iPad 3 (GSM)"; if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4 (WiFi)"; if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4 (GSM)"; if ([platform isEqualToString:@"iPad3,6"]) return @"iPad 4 (GSM+CDMA)"; if ([platform isEqualToString:@"iPad4,1"]) return @"iPad Air (WiFi)"; if ([platform isEqualToString:@"iPad4,2"]) return @"iPad Air (Cellular)"; if ([platform isEqualToString:@"iPad4,4"]) return @"iPad mini 2G (WiFi)"; if ([platform isEqualToString:@"iPad4,5"]) return @"iPad mini 2G (Cellular)"; if ([platform isEqualToString:@"i386"]) return @"Simulator"; if ([platform isEqualToString:@"x86_64"]) return @"Simulator"; return platform; } 

因此,我应该假设iPhone7,1iPhone7,2是iPhone 6,而iPhone7,3iPhone7.4是增加的? 如果有人有更具体的方式来告诉它会很好,谢谢。

第一个屏幕将是设备屏幕,请注意,之前必须添加新手机的启动图像,否则应用程序会以较大的应用程序的缩放模式运行:以下是我用来检查的代码。 注意:这仅适用于iOS 8及更高版本

 UIScreen *mainScreen = [UIScreen mainScreen]; NSLog(@"Screen bounds: %@, Screen resolution: %@, scale: %f, nativeScale: %f", NSStringFromCGRect(mainScreen.bounds), mainScreen.coordinateSpace, mainScreen.scale, mainScreen.nativeScale); 

检测iPhone 6 Plus的代码:

 #define IS_PAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) #define IS_PHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) -(BOOL)iPhone6PlusDevice{ if (!IS_PHONE) return NO; if ([UIScreen mainScreen].scale > 2.9) return YES; // Scale is only 3 when not in scaled mode for iPhone 6 Plus return NO; } 

要么

 -(BOOL) iPhone6PlusUnZoomed{ if ([self iPhone6PlusDevice]){ if ([UIScreen mainScreen].bounds.size.height > 720.0) return YES; // Height is 736, but 667 when zoomed. } return NO; } 

注意:如果您正在检查iPhone 6 Plus,要调整用户界面,则不要依赖.nativeScale ,因为模拟器和实际设备会给出不同的结果。 由于下面的评论。 Scale是一个CGFloat,因此,代码不应该检查相等性,因为一些浮动值可能永远不会相等。


为新的iPhone66Plus添加启动图像后,尺寸会发生变化。 他们缩放较旧的应用程序来适应屏幕。

(Apple名称: Retina HD 5.5 ),坐标空间: 414 x 736点和1242 x 2208像素,401 ppi,屏幕物理尺寸为2.7 x 4.8英寸或68 x 122 mm

 Screen bounds: {{0, 0}, {414, 736}}, Screen resolution: <UIScreen: 0x7f97fad330b0; bounds = {{0, 0}, {414, 736}}; mode = <UIScreenMode: 0x7f97fae1ce00; size = 1242.000000 x 2208.000000>>, scale: 3.000000, nativeScale: 3.000000 

尺寸为iPhone 6iPhone 6S (Apple名称: Retina HD 4.7 ),坐标空间: 375 x 667点, 750 x 1334像素,326 ppi,屏幕物理尺寸为2.3 x 4.1英寸或58 x 104毫米

 Screen bounds: {{0, 0}, {375, 667}}, Screen resolution: <UIScreen: 0x7fa01b5182d0; bounds = {{0, 0}, {375, 667}}; mode = <UIScreenMode: 0x7fa01b711760; size = 750.000000 x 1334.000000>>, scale: 2.000000, nativeScale: 2.000000 

iPhone 5比较是640×1136, iPhone 4 640×960。

注意:上传LaunchImages否则应用程序将运行缩放,不显示正确的缩放比例或屏幕大小。

比较iPhone 6和6 Plus

如果你喜欢macros,那么你可以用它来区分iPhone模型。 这些基于点值。

 #define IS_IPHONE_4 (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)480) < DBL_EPSILON) #define IS_IPHONE_5 (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)568) < DBL_EPSILON) #define IS_IPHONE_6 (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)667) < DBL_EPSILON) #define IS_IPHONE_6_PLUS (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)736) < DBL_EPSILON) 

我使用下面的代码来确定什么设备正在运行(这有点快而肮脏,但它的确有窍门)

 if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone ){ CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; if( screenHeight < screenWidth ){ screenHeight = screenWidth; } if( screenHeight > 480 && screenHeight < 667 ){ NSLog(@"iPhone 5/5s"); } else if ( screenHeight > 480 && screenHeight < 736 ){ NSLog(@"iPhone 6"); } else if ( screenHeight > 480 ){ NSLog(@"iPhone 6 Plus"); } else { NSLog(@"iPhone 4/4s"); } } 

(只有通过添加适当的启animation面才能启用iPhone 6/6 Plus)

在物理设备上,iPhone 6 Plus的主屏幕边界是2208×1242,nativeBounds是1920×1080。 有硬件缩放涉及调整到物理显示。

在模拟器上,iPhone 6 Plus的主屏幕边界和nativeBounds都是2208×1242。

换句话说,video,OpenGL和基于CALayers的其他处理像素的东西将会处理设备上的真实1920×1080帧缓冲区(或者SIM卡上的2208×1242)。 处理UIKit中的点的事情将处理2208×1242(x3)的边界,并在设备上适当缩放。

模拟器无法访问在设备上进行缩放的相同硬件,在软件中进行模拟没有太大好处,因为它们会产生与硬件不同的结果。 因此,将模拟设备的主屏幕的nativeBounds设置为物理设备主屏幕的边界是有意义的。

iOS 8为UIScreen(nativeScale和nativeBounds)添加了API,以便开发人员确定与UIScreen相对应的CAD显示的分辨率。

检查维基上的更新列表,那里我得到了iPhone 7的7,2和iPhone 7的7.1。

您可以使用以下macros来检测iPhone 6 Plus的原生规模:

 #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) #define IS_IPHONE_6PLUS (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f) 

Hannes Sverrisson的回答几乎是正确的。 iPhone 6坐标系实际上大于5s使用他的代码:

 UIScreen *mainScreen = [UIScreen mainScreen]; NSLog(@"Screen bounds: %@, Screen resolution: %@, scale: %f, nativeScale: %f", NSStringFromCGRect(mainScreen.bounds), mainScreen.coordinateSpace, mainScreen.scale, mainScreen.nativeScale); 

提供正确启动图像的应用程序的坐标系是:

尺寸为iPhone 6(Retina HD 4.7),尺寸为@ 2x,坐标空间:375 x 667和750 x 1334实际点数:

 Screen bounds: {{0, 0}, {375, 667}}, Screen resolution: <UIScreen: 0x7fa01b5182d0; bounds = {{0, 0}, {375, 667}}; mode = <UIScreenMode: 0x7fa01b711760; size = 750.000000 x 1334.000000>>, scale: 2.000000, nativeScale: 2.000000 

尺寸为iPhone 6 Plus(Retina HD 5.5),尺寸为@ 3x,坐标空间:414 x 736和1242 x 2208实际点数:

 Screen bounds: {{0, 0}, {414, 736}}, Screen resolution: <UIScreen: 0x7f97fad330b0; bounds = {{0, 0}, {414, 736}}; mode = <UIScreenMode: 0x7f97fae1ce00; size = 1242.000000 x 2208.000000>>, scale: 3.000000, nativeScale: 3.000000 

这是我在iOS 8的应用程序中使用的:

 window=[[[UIApplication sharedApplication] windows] firstObject]; NSLog(@"screenHeight=%f width=%f",window.frame.size.height,window.frame.size.width); if (window.frame.size.height == 480) { do stuff here... } 

在Xcode6 / iOS 8之前,我使用了这个,但屏幕边界不能用可resize的模拟器正常工作,或者至less它不在Xcode6 beta版中。

 CGRect screenBounds=[[UIScreen mainScreen] bounds]; if (screenBounds.size.height >= 568) { do stuff here... } 

我必须在使用iOS 7构build的应用程序中检测iPhone 6 Plus。因为nativeScale在[UIScreen mainScreen]上不可用,所以我尝试使用[UIScreen mainScreen] scale],但是这只是返回2.0。 所以我想出了这个解决scheme来检测iOS 7上的iPhone 6 Plus(也应该在iOS 8上工作):

 -(BOOL)iPhone6Plus{ BOOL isiPhone6Plus = NO; SEL selector = NSSelectorFromString(@"scale"); if ([[UIScreen mainScreen] respondsToSelector:selector]) { NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: [[[UIScreen mainScreen] class] instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:[UIScreen mainScreen]]; [invocation invoke]; float returnValue; [invocation getReturnValue:&returnValue]; if (returnValue == 3.0) { isiPhone6Plus = YES; } NSLog(@"ScaleFactor %1.2f", returnValue); } return isiPhone6Plus; 

}

这个代码的有趣的部分是,如果我使用NSInvocation的比例select器的返回值将3.0。 直接在iOS 7上调用此方法将返回2.0。

所有三个设备都有(几乎)每英寸相同的点数。 所以你的图像将自动具有相同的物理尺寸。

使用[[UIScreen mainScreen] bounds]获取屏幕上的点数。 如果你真的想要的话,用163除以得到大约的尺寸。

请注意,6+不会返回1080p,因为它不会呈现到1080p缓冲区。 它呈现这样的结果,每英寸输出约为160点,使用@ 3x资产。

无需再次猜测。

例如,如果你写这个代码:

 UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 163, 163)]; view.backgroundColor = [UIColor redColor]; [self.view addSubview:view]; 

在所有iOS设备上,您都会看到几乎相同的物理尺寸(一平方英寸)。

苹果已经做了很多努力,所以你不必这样做。

对我来说这适合我

 if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){ UIStoryboard *storyBoard; CGSize result = [[UIScreen mainScreen] bounds].size; CGFloat scale = [UIScreen mainScreen].scale; result = CGSizeMake(result.width * scale, result.height * scale); if(result.height == 1136){ storyBoard = [UIStoryboard storyboardWithName:@"Main_iPhone_5" bundle:nil]; UIViewController *initViewController = [storyBoard instantiateInitialViewController]; [self.window setRootViewController:initViewController]; } else if(result.height == 1334){ storyBoard = [UIStoryboard storyboardWithName:@"Main_iPhone_6" bundle:nil]; UIViewController *initViewController = [storyBoard instantiateInitialViewController]; [self.window setRootViewController:initViewController]; } else if(result.height == 2208){ storyBoard = [UIStoryboard storyboardWithName:@"Main_iPhone_6_plus" bundle:nil]; UIViewController *initViewController = [storyBoard instantiateInitialViewController]; [self.window setRootViewController:initViewController]; } else if(result.height == 960){ storyBoard = [UIStoryboard storyboardWithName:@"Main_iPhone_4" bundle:nil]; UIViewController *initViewController = [storyBoard instantiateInitialViewController]; [self.window setRootViewController:initViewController]; } } else { UIStoryboard *storyBoard; storyBoard = [UIStoryboard storyboardWithName:@"Main_iPad" bundle:nil]; UIViewController *initViewController = [storyBoard instantiateInitialViewController]; [self.window setRootViewController:initViewController]; } 

这是保证在Xcode 5编译(在这一点上的XCDE 6仍然是片状,你不能提交一个IAP的iTunes连接应用程序商店批准使用testing版软件,现在Xcode 6)

事情是Xcode 5将无法识别nativeScaleselect器..这是你如何可以在运行时做到这一点:

 + (BOOL)isIphone6Plus { SEL selector = NSSelectorFromString(@"nativeScale"); if ([[UIScreen mainScreen] respondsToSelector:selector]) { NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: [[[UIScreen mainScreen] class] instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:[UIScreen mainScreen]]; [invocation invoke]; float returnValue; [invocation getReturnValue:&returnValue]; NSLog(@"::: this is native scale %f", returnValue); return (returnValue == 3.0f); } else { // iphone 6 plus come prepackaged with iOS8.. // so if the phone doesn't know what nativeScale means // it's not an iphone6plus phone return NO; } } 

在我的iPhone 6 Plus上阅读屏幕尺寸时,需要记住的一件有趣的事情是,当您将其设置为“缩放”模式时,它将显示为iPhone 6的高度(667),如果将其设置为“标准”将显示为(736)。 实际上应该不重要,但是如果您因为某种原因(也许是报告)特别想知道设备types,这可能会欺骗你。

看到这个

这里是你正在使用这个更新的源代码。

iPhone 6和iPhone 6 Plus型号已被添加。

上述答案的一个主要的缺陷是,在iOS7及以下版本中,当您检查屏幕边界的[[UIScreen mainScreen] bounds] ,无论手机的方向如何,它总是列出宽度和高度所以如果它是横向模式下的iPhone5,它仍然会列出宽度为320,高度为568.在iOS8中,这个改变了,现在如果相同的iPhone5在横向,它将列出宽度为568,高度为320.以下是解释这个的方法:

 + (BOOL) deviceHasFourInchScreen { return [DeviceType deviceHasScreenWithIdiom:UIUserInterfaceIdiomPhone scale:2.0 height:568.0]; } + (BOOL) deviceHasFourPointSevenInchScreen { return [DeviceType deviceHasScreenWithIdiom:UIUserInterfaceIdiomPhone scale:2.0 height:667.0]; } + (BOOL) deviceHasFivePointFiveInchScreen { return [DeviceType deviceHasScreenWithIdiom:UIUserInterfaceIdiomPhone scale:3.0 height:736.0]; } + (BOOL) deviceHasScreenWithIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom scale:(CGFloat)scale height:(CGFloat)height { CGRect mainScreenBounds = [[UIScreen mainScreen] bounds]; CGFloat mainScreenHeight; if ([OperatingSystemVersion operatingSystemVersionLessThan:@"8.0"]) { mainScreenHeight = mainScreenBounds.size.height; } else { mainScreenHeight = (UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) ? mainScreenBounds.size.width : mainScreenBounds.size.height; } if ([[UIDevice currentDevice] userInterfaceIdiom] == userInterfaceIdiom && [[UIScreen mainScreen] scale] == scale && mainScreenHeight == height) { return YES; } else { return NO; } } 

这里还有OperatingSystem类的方法:

 + (NSString *) currentOperatingSystemVersion { return [[UIDevice currentDevice] systemVersion]; } + (BOOL) operatingSystemVersionLessThanOrEqualTo:(NSString *) operatingSystemVersionToCompare { return ([[self currentOperatingSystemVersion] compare: operatingSystemVersionToCompare options:NSNumericSearch] != NSOrderedDescending); }