7

I am setting up an application where I want to make a number of changes to the view layout based on the type of iPhone in use. Specifically I want to know if the vertical screen resolution is 1136 (iPhone5) or 960 (iPhone4). One of the things I want to do is adjust the height of my UITableViewCells in a UITableView so that no partial cells are displayed when the app is run on either phone.

My question is: what is the best way to detect the phone hardware type in use so that I can make the appropriate changes to my view layout?

Krishnabhadra
  • 34,169
  • 30
  • 118
  • 167
fuzzygoat
  • 26,573
  • 48
  • 165
  • 294
  • Some good answers, http://stackoverflow.com/questions/1108859/detect-the-specific-iphone-ipod-touch-model – Rukshan Oct 24 '12 at 12:10

5 Answers5

16

I dont have iphone 5 but on the other phone this code worked great:

NSMutableDictionary *devices = [[NSMutableDictionary alloc] init];
[devices setObject:@"simulator"                     forKey:@"i386"];
[devices setObject:@"iPod Touch"                    forKey:@"iPod1,1"];
[devices setObject:@"iPod Touch Second Generation"  forKey:@"iPod2,1"];
[devices setObject:@"iPod Touch Third Generation"   forKey:@"iPod3,1"];
[devices setObject:@"iPod Touch Fourth Generation"  forKey:@"iPod4,1"];
[devices setObject:@"iPhone"                        forKey:@"iPhone1,1"];
[devices setObject:@"iPhone 3G"                     forKey:@"iPhone1,2"];
[devices setObject:@"iPhone 3GS"                    forKey:@"iPhone2,1"];
[devices setObject:@"iPad"                          forKey:@"iPad1,1"];
[devices setObject:@"iPad 2"                        forKey:@"iPad2,1"];
[devices setObject:@"iPhone 4"                      forKey:@"iPhone3,1"];
[devices setObject:@"iPhone 4S"                     forKey:@"iPhone4"];
[devices setObject:@"iPhone 5"                      forKey:@"iPhone5"];

- (NSString *) getDeviceModel
{
    struct utsname systemInfo;
    uname(&systemInfo);
    return [devices objectForKey:[NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]];
}

Remember to import:

#import "sys/utsname.h"
edzio27
  • 4,126
  • 7
  • 33
  • 48
  • 2
    This should be the answer. Relying in the screen size is wrong in so many levels. – 3d0 Feb 28 '13 at 22:54
  • @3d0, what would be one level that relying on the screen size is wrong? – ari gold May 13 '13 at 07:10
  • You know you can build an iPhone5 compatible app using the size of the previous iPhones (your app will have black borders). If you use the screen size, the system will yield the size of the app (the same size of iPhone4). In the simulator is worse. – 3d0 May 22 '13 at 22:45
  • You asked for a scenario: I have an app that functions fine on the iphone5, a little slow on the 4s, and extremely slow on the 4. I can tell 4/4s from screen height, but this won't tell me which device it is between the two. I could run a speed test, check the result, and then make a decision based on that, but that would waste time. It's not a good user experience. IN one quick check to know then I can set parameters to make it run better on each specific device. That's my plan anyway. – badweasel Oct 06 '13 at 10:23
  • on my `4S` this code returns `iPhone4,1`. For 5 it returns `iPhone5,1`. Perhaps models changed in two years? – Andrei G. Dec 06 '14 at 21:10
8

You should really use the autolayout features to make your views adapt to whatever format the screen is.

However, if you only want to know if the device is an iPhone 5 (ie has 1136px in height) you could use:

[ [ UIScreen mainScreen ] bounds ].size.height

Could ofcourse be turned into a macro.

Johan André
  • 129
  • 3
  • 1
    I don't think you can use autolayout to set the height of UITableViewCells, I will have another look just in case I missed something. – fuzzygoat Oct 24 '12 at 10:07
  • I think you can. Define your own constraints programmatically using NSLayoutConstraint. – Johan André Jan 30 '13 at 20:47
  • Could you use autolayout and still properly handle the differences in layout between an iPhone4 and iPhone5? – ari gold May 13 '13 at 06:06
2
#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)

define this macro in some constant.h file and use it any where to check

if(IS_IPHONE5)
{
// iphone 5
}
else
{
// earlier
}
Saad
  • 8,857
  • 2
  • 41
  • 51
2

From your question ,it seems you want to correct UI depending on device and resolution. In that case, it is fine and you can use below given code to identify the device. But for non UI things, like looking for a device capability which is present in one device, absent in other, It is always advised to check for whether that capability is present, rather than which is the device model. From apple's official forum. (login required)

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
  if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)]) {
    CGSize result = [[UIScreen mainScreen] bounds].size;
    CGFloat scale = [UIScreen mainScreen].scale;
    result = CGSizeMake(result.width * scale, result.height * scale);

    if(result.height == 960){
      NSLog(@"iphone 4, 4s retina resolution");
    }
    if(result.height == 1136){
      NSLog(@"iphone 5 resolution");
    }
  }else{
    NSLog(@"iphone standard resolution");
  }
}else{
  if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)]) {
    NSLog(@"ipad Retina resolution");
  }else{
    NSLog(@"ipad Standard resolution");
  }
}
Krishnabhadra
  • 34,169
  • 30
  • 118
  • 167
1

I've been checking aspect ratio. Not as general as some of the other methods but still more flexible for future devices than checking a specific resolution.

// 0.563380 = 16x9 (iPhone 5)
// 0.666667 = 3x2  (iPhone 4S and previous)
CGFloat aspectRatio = [UIScreen mainScreen].bounds.size.width / [UIScreen mainScreen].bounds.size.height;
// Tall Screen
if (aspectRatio > 0.55 && aspectRatio < 0.57) {
    // Tall screen stuff.
    }

    // Short Screen
} else if (aspectRatio > 0.64 && aspectRatio < 0.68) {

    // Short screen stuff.
    }
}
Michael Mangold
  • 1,741
  • 3
  • 18
  • 32