58

Given the newly announced iPhone 6 screen sizes:

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

I was wondering if there is code that allows me to detect which screen size the user's device is, so that I could adjust and size UIImages and other materials accordingly with the user's device.

So far, I have been using the following:

- (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;
}

As such, should I assume iPhone7,1 and iPhone7,2 are the iPhone 6 while iPhone7,3 and iPhone7.4 are the pluses? If anyone has more concrete way to tell it'd be great, thanks.!

daspianist
  • 5,336
  • 8
  • 50
  • 94
  • 3
    It is not recommended that you alter behavior based on the device model. Instead, use capabilities. In the case of images, just continue using 2x, 3x, etc. – quellish Sep 10 '14 at 01:58
  • 2
    According to [this answer](http://stackoverflow.com/a/25898658/1693173) the string `iPhone7,1` is the 6 plus, while the `iPhone7,2` is the 6. – progrmr Sep 19 '14 at 21:59
  • Check this post: http://stackoverflow.com/questions/3339722/how-to-check-ios-version/26087033#26087033 – Aritra Das Sep 28 '14 at 16:31

16 Answers16

101

The first screen will be the device screen, Note that a launch images for the new phones have to be added before, otherwise the app is running in Zoomed Mode for older apps : Here is the code I used to check this out. Note: This only works with version iOS 8 and higher:

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

Code for detecting 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;
}

or

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

Note: If you are checking for iPhone 6 Plus, to adjust the user interface then don´t rely on .nativeScale, because the simulator and actual device give different results. Due to the comment below. Scale is a CGFloat and thus, code should not check equality, because some floats values may never be equal.


After adding Launch Screen you can utilise the new iPhone sizes, otherwise your app will still look scaled.

Updated for the new iPhones 11, 11 Pro and 11 Pro Max

Size for iPhone 11 Pro Max with @3x scaling, coordinate space: 414 x 896 points and 1242 x 2688 pixels, 458 ppi, device physical size is 3.06 x 6.22 in or 77.8 x 158.0 mm. 6.5" Super Retina XDR display.

Size for iPhone 11 Pro with @3x scaling, coordinate space: 375 x 812 points and 1125 x 2436 pixels, 458 ppi, device physical size is 2.81 x 5.67 in or 71.4 x 144.0 mm. 5.8" Super Retina XDR display.

Size for iPhone 11 with @2x scaling, coordinate space: 414 x 896 points and 828 x 1792 pixels, 326 ppi, device physical size is 2.98 x 5.94 in or 75.7 x 150.9 mm. 6.1" Liquid Retina HD display.

Size for iPhone X Max with @3x scaling (Apple name: Super Retina HD 6.5 display"), coordinate space: 414 x 896 points and 1242 x 2688 pixels, 458 ppi, device physical size is 3.05 x 6.20 in or 77.4 x 157.5 mm.

let screen = UIScreen.main
print("Screen bounds: \(screen.bounds), Screen resolution: \(screen.nativeBounds), scale: \(screen.scale)")
//iPhone X Max Screen bounds: (0.0, 0.0, 414.0, 896.0), Screen resolution: (0.0, 0.0, 1242.0, 2688.0), scale: 3.0

Size for iPhone X with @2x scaling (Apple name: Super Retina HD 6.1" display), coordinate space: 414 x 896 points and 828 x 1792 pixels, 326 ppi, device physical size is 2.98 x 5.94 in or 75.7 x 150.9 mm.

let screen = UIScreen.main
print("Screen bounds: \(screen.bounds), Screen resolution: \(screen.nativeBounds), scale: \(screen.scale)")
//iPhone X Screen bounds: (0.0, 0.0, 414.0, 896.0), Screen resolution: (0.0, 0.0, 828.0, 1792.0), scale: 2.0

Size for iPhone X and iPhone X with @3x scaling (Apple name: Super Retina HD 5.8" display), coordinate space: 375 x 812 points and 1125 x 2436 pixels, 458 ppi, device physical size is 2.79 x 5.65 in or 70.9 x 143.6 mm.

let screen = UIScreen.main
print("Screen bounds: \(screen.bounds), Screen resolution: \(screen.nativeBounds), scale: \(screen.scale)")
//iPhone X and X Screen bounds: (0.0, 0.0, 375.0, 812.0), Screen resolution: (0.0, 0.0, 1125.0, 2436.0), scale: 3.0

Size for iPhone 8, 7, 6 Plus and iPhone 8, 7, 6S Plus with @3x scaling (Apple name: Retina HD 5.5), Coordinate space: 414 x 736 points and 1242 x 2208 pixels, 401 ppi, screen physical size is 2.7 x 4.8 in or 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

Size for iPhone 6 and iPhone 6S with @2x scaling (Apple name: Retina HD 4.7), Coordinate space: 375 x 667 points and 750 x 1334 pixels, 326 ppi, screen physical size is 2.3 x 4.1 in or 58 x 104 mm:

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

And iPhone 5 for comparison is 640 x 1136, iPhone 4 640 x 960.

Note: Upload LaunchImages otherwise the app will run scaled and not show correct scaling, or screen sizes.

Comparing iPhone 6 and 6 Plus

Sverrisson
  • 17,970
  • 5
  • 66
  • 62
  • Thanks for the detailed outputs - this is especially helpful to know the exact point values (and also strange that its different on the website) – daspianist Sep 10 '14 at 02:02
  • 2
    @daspianist I have updated my comment after adding startup images for the new phones, otherwise the simulator is running in scaling mode for older Apps and thus, previous resolution was not shown. – Sverrisson Sep 10 '14 at 10:40
  • 1
    "Coordinate space: 414 x 716" - fix 716 to 736 – KAMIKAZE Sep 10 '14 at 12:39
  • After adding startup image, i get correct screen bounds as per iPhone 6 and iPhone 6+ however, when i try NSLog(@"ViewBounds: %@",NSStringFromCGRect(self.view.bounds)); to check View controller's bounds, i get 320 x 568 even if i'm running in iPhone 6 simulator, is it normal ?? – DevCali Sep 12 '14 at 23:16
  • @Developer007 The numbers that you get for iPhone 6 320 x 568 are the correct bounds sizes. It shows you the points, but the actual pixel resolution is double that, hence the scale 2x. – Sverrisson Sep 12 '14 at 23:20
  • but i thought iPhone 6 bounds should be {{0, 0}, {375, 667}} ?? – DevCali Sep 12 '14 at 23:24
  • Create answer really. – Danny Xu Sep 23 '14 at 05:22
  • how do i know for sure that the compiler is using my @2 x and @ 3x images other then my own eyes? – 4GetFullOf Sep 23 '14 at 14:23
  • 1
    If you are using the scaled version of the app, that code check will not work. You can check the native scale instead to work in every case: if (([[UIScreen mainScreen] respondsToSelector:@selector(nativeScale)]) && ([UIScreen mainScreen].nativeScale > 2.1)) return YES; – Tiago Lira Sep 26 '14 at 11:16
  • @TiagoLira But if the user is running in Scaled mode then the App sees the same size as an iPhone 5 sees, so you would´t want to adjust. I will clarify this in the answer. – Sverrisson Sep 26 '14 at 15:55
  • That is a good point, it depends on what you need! on my case I was using the scaled version but i still needed to detect it as the 6plus was showing some different behaviours :) – Tiago Lira Sep 27 '14 at 19:34
  • Minor note: you can just return `[UIScreen mainScreen].nativeScale > 2.1` directly. There's no need for separate return statements. – Wayne Oct 07 '14 at 21:50
  • @lwburk Yes, you can return it directly. I just use return statements because it´s easier to check and reuse them. – Sverrisson Oct 07 '14 at 23:05
  • Note that checking `nativeScale` only works with iOS 8. If you are still supporting iOS 7, you need to check using `respondsToSelector` like @TiagoLira suggests or else your app will crash. – Kyle Clegg Oct 13 '14 at 18:56
  • @KyleClegg Yes, I clarify that in the comments but will fix the code accordingly. – Sverrisson Oct 13 '14 at 20:11
  • check out adding a storyboard scene as an alternative to adding launch images to an app http://oleb.net/blog/2014/08/replacing-launch-images-with-storyboards/ – Carl Oct 31 '14 at 11:51
  • 3
    On comparing a float set to 3.0 with the value 3.0... they are both floats so will both 'suffer' the same loss of accuracy when represented in binary. .scale == 3.0 is a valid (and clear) comparison to use – Carl Oct 31 '14 at 11:53
  • @Carl furthermore, floats can exactly represent integers up to a certain point (one that most definitely includes 3) – Loyal Tingley Apr 23 '15 at 02:18
  • @LoyalTingley you down vote for that! Sometimes the iPhone 6 plus gives a scale less than 3.0 when in Zoomed mode. – Sverrisson Apr 23 '15 at 04:07
  • @TiagoLira nativeScale does not work in my case: it gives 2.0 for a Iphone6 runing an app in iphone5 scaled mode (due lacking launch image) . I cannot detect this points per inch / or centimer, to display a correct ruler of exactly 1cm. – AlexWien Jul 25 '15 at 20:02
  • @AlexWien do you get the same result in scale and nativeScale? If they are different, maybe you can use that to detect the stretched version... – Tiago Lira Jul 26 '15 at 12:57
  • @HannesSverrisson What do you mean? I did not downvote. – Tiago Lira Jul 26 '15 at 12:58
  • @TiagoLira You don't need nativeScale to draw to scale. Just, calculate everything in points and then the phone will scale appropriately in it's native resolution: screen.bounds.size.height point / 12.2cm * 1cm = 60.328 points for iPhone 6 Plus and do similar for iPhone 6. – Sverrisson Jul 26 '15 at 17:01
  • @TiagoLira I get the same for scale and native scale. They only way to detect stretched mode, seems to be by using machineName(). That worked, however it did not help me much. I gave up and added a iphone6 (universal) launch.xib (so it seems not to be easy to display a ruler of exactly 1cm in all (stretched) modes) – AlexWien Jul 26 '15 at 23:01
30

If you prefer macros here are the ones, that you can use to differentiate between the iPhone models. These are based on the point values.

#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)
bkhayll
  • 317
  • 2
  • 3
17

I use the following code to determine what device is running (it's a little bit quick and dirty but it does the trick)

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");
    }
}

(This only works when iPhone 6 / 6 Plus is enabled by adding the appropriate splash screens)

Roland Keesom
  • 8,180
  • 5
  • 45
  • 52
  • 1
    It doesnt work. I am trying it on iPhone 6 device and it returns iPhone 5/5s log. It is weird but screenHeight look 568 like iPhone 5 with these codes. – Yucel Bayram Nov 10 '14 at 14:56
  • Do you have your app enabled for the iPhone 6 / 6 plus by adding the splash screens? – Roland Keesom Nov 11 '14 at 07:51
  • No i did not set images to lanuch image for 4.7 hd screen. I ll try this. thanks – Yucel Bayram Nov 11 '14 at 08:10
  • When i set image for 4.7 inch, app looks smallar anymore on screen. Its like empty places from right and down. Do you have an idea? – Yucel Bayram Nov 11 '14 at 08:42
  • This is because you enabled the 4.7 inch layout. You probably need to adjust your screens with autolayout, see for more info about autolayout:http://mobileoop.com/how-to-use-auto-layout-in-xcode-6-for-ios-7-and-8-development – Roland Keesom Nov 11 '14 at 08:51
4

On the physical device, iPhone 6 Plus's main screen's bounds is 2208x1242 and nativeBounds is 1920x1080. There is hardware scaling involved to resize to the physical display.

On the simulator, the iPhone 6 Plus's main screen's bounds and nativeBounds are both 2208x1242.

In other words... Videos, OpenGL, and other things based on CALayers that deal with pixels will deal with the real 1920x1080 framebuffer on device (or 2208x1242 on sim). Things dealing with points in UIKit will be deal with the 2208x1242 (x3) bounds and get scaled as appropriate on device.

The simulator does not have access to the same hardware that is doing the scaling on device and there's no really much of a benefit to simulating it in software as they'd produce different results than the hardware. Thus it makes sense to set the nativeBounds of a simulated device's main screen to the bounds of the physical device's main screen.

iOS 8 added API to UIScreen (nativeScale and nativeBounds) to let a developer determine the resolution of the CADisplay corresponding to the UIScreen.

Jeremy Huddleston Sequoia
  • 22,938
  • 5
  • 78
  • 86
4

You can detect iPhone 6 Plus based on its native scale, using this macro:

#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_6PLUS (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f)
sweepy_
  • 1,333
  • 1
  • 9
  • 28
4

Check the updated list on wiki , there I got 7,2 for iPhone 6 and 7,1 for iPhone 6 plus.

ares777
  • 3,590
  • 1
  • 22
  • 23
3

Hannes Sverrisson's answer is almost correct. The iPhone 6 coordinate system is in fact larger than the 5s Using his code:

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

The coordinate system for apps providing the correct launch images are:

Size for iPhone 6 (Retina HD 4.7) with @2x scaling, Coordinate space: 375 x 667 and 750 x 1334 actual points:

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

Size for iPhone 6 Plus (Retina HD 5.5) with @3x scaling, Coordinate space: 414 x 736 and 1242 x 2208 actual points:

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
2

This is what I use in my app with 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... 
    }

Prior to Xcode6 / iOS 8, I used this, but screen bounds does not work properly with the resizable simulator or at least it didn't in the Xcode6 betas...

CGRect screenBounds=[[UIScreen mainScreen] bounds];

if (screenBounds.size.height >= 568) {

do stuff here...

}
David L
  • 4,347
  • 3
  • 18
  • 30
2

All three devices have (pretty much) the same number of points per inch. So your images will automatically be the same physical size.

Use [[UIScreen mainScreen] bounds] to get the total number of points on the screen. Divide by 163 to get the approximate size in inches if you really want it.

Notice that the 6+ does not return 1080p because it doesn't render to a 1080p buffer. It renders such that output is approximately 160 points per inch, using @3x assets.

No need to second guess.

E.g. if you write this code:

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

You'll get a view that is pretty much the same physical size — one inch square — on all iOS devices.

Apple has already done the hard work, so you don't have to.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • Thanks for the suggestion! I asked this because I was using the following `self.keyboardOverlayView.frame = CGRectMake(0, 0, 320, 216);` and it appears that while the keyboard would cover the entire width on the 5/5s devices, when running on the simulator for the 6 or 6s, there are white gaps. I guess I should use view.size.width to be dynamic, but wanted to see if there is a way to also get the device information for other uses. – daspianist Sep 10 '14 at 02:01
  • 1
    I would dare imagine keyboards will resize overlay views so just make sure its subviews have appropriate constraints or autoresizing masks but, if keyboards don't, I guess crib it from `mainScreen`. – Tommy Sep 10 '14 at 02:10
2

I had to detect the iPhone 6 Plus in an app built with iOS 7. Because nativeScale isn't available on [UIScreen mainScreen] I tried to use [UIScreen mainScreen] scale] but this just returned 2.0. So I came up with this solution to detect the iPhone 6 Plus on iOS 7 (should also work on 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;

}

The interesting part of this code is, that if I use NSInvocation the return value of the scale selector will be 3.0. Calling this method directly on iOS 7 returns 2.0.

Sven
  • 56
  • 5
  • 1
    iPhone 6 and the 6 Plus don't run iOS7. So the check seems pointless? – Robert J. Clegg Dec 30 '14 at 12:32
  • 1
    It isn't pointless because you may have an app running on iOS 7 which should do special things (like another layout) on an iPhone 6 Plus. And the code should run on iOS 7 and iOS 8 as well. – Sven Apr 21 '15 at 13:33
2

to me this works for me

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];

}
oscar castellon
  • 3,048
  • 30
  • 19
1

Here is the updated source code you are using this.

iPhone 6 and iPhone 6 Plus models have been added.

itzmebibin
  • 9,199
  • 8
  • 48
  • 62
1

An interesting thing to remember when reading screen sizes on my iPhone 6 Plus was that when you have it set to "Zoomed" mode it will show up as a the iPhone 6 height (667) and when you have it set to "Standard" it will show up as (736). Shouldn't really matter, but if you specifically wanted to know the device type for some reason ( Maybe Reporting ), this could fool you.

See this.

itzmebibin
  • 9,199
  • 8
  • 48
  • 62
Shippy
  • 61
  • 1
  • 3
0

One major thing that the above answers are leaving out is the fact that in iOS7 and below, when you check [[UIScreen mainScreen] bounds] for the screen bounds, it always lists the width and height as the same no matter what orientation the phone is in. So if it's an iPhone5 in landscape mode, it will still list the width as 320 and height as 568. In iOS8, this changed, now if that same iPhone5 is in landscape, it will list the width as 568 and the height as 320. Below are methods which account for this:

+ (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;
    }
}

Also here are the accompanying OperatingSystem class methods:

+ (NSString *) currentOperatingSystemVersion
{
    return [[UIDevice currentDevice] systemVersion];
}
+ (BOOL) operatingSystemVersionLessThanOrEqualTo:(NSString *) operatingSystemVersionToCompare
{
    return ([[self currentOperatingSystemVersion] compare: operatingSystemVersionToCompare options:NSNumericSearch] != NSOrderedDescending);    
}
Ser Pounce
  • 14,196
  • 18
  • 84
  • 169
0

this is guaranteed to compile in xcode 5 (xocde 6 at this point is still flaky, and you can't submit an ipa to itunes connect for app store approval using beta software, which xcode 6 is right now)

the thing is xcode 5 won't recognize the nativeScale selector.. this is how you can do it in run time:

+ (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;
    }
}
abbood
  • 23,101
  • 16
  • 132
  • 246
0

Swift 4

let kSize = UIScreen.main.bounds.size //kSize is screen CGSize

if(kSize.width == 320){
             //iphone se
}else if(kSize.width == 375 && kSize.height == 667){
             //iphone 7 / 8
}else if(kSize.width == 375){
            //iphone x
}else if(kSize.width == 414){
           //iphone 7 plus/ 8 plus
}
Kishore Kumar
  • 4,265
  • 3
  • 26
  • 47