13

How can I programmatically (Objective-C) whether an iPad has a Retina display?

bobobobo
  • 64,917
  • 62
  • 258
  • 363
António
  • 975
  • 1
  • 12
  • 31
  • 7
    Why? In general you should detect and adjust for _features_ rather than specific devices. – Stephen Darlington Mar 13 '12 at 17:27
  • @StephenDarlington - My application is only for iPad, and the new iPad has a bigger resolution. I just need to add on code the new values for screen resolution. – António Mar 13 '12 at 17:39
  • 3
    @Freedom - You don't have to code differently for the new iPad. The frames and positioning of your views will not be changed. If you have images, simply add `@2x` versions of them that have double dimensions but your code will not change, there are only new image files to add. – sch Mar 13 '12 at 17:44
  • I have a viewcontroller that is build programmatically (depends on the data received from web service). This viewcontroller, has a UITableView controller, and i would like to add some more information on UITableViewCell for the new iPad (because has a bigger screen resolution, so has more space). – António Mar 13 '12 at 17:57
  • 3
    @Freedom It doesn't really have more space. The screen is still the same size physically. 10pt text is still 10pt in size. People's fingers are still the same size. – Stephen Darlington Mar 13 '12 at 18:39
  • @StephenDarlington This is going beyond the scope of the topic, but e.g: if I have a UILabel from 0 to 300 (...CGRectMake(0, 300, 300, 50)) and other from 300 to 700 (...CGRectMake(300, 700, 300, 50)), on iPad 3 I will have free space on the right side? or I am doing a big confusion because of the resolution of the screen? – António Mar 14 '12 at 09:10
  • 1
    @Freedom No, you won't have free space on the right side. It will be the same as on the iPad 2, though the text will be sharper. – Stephen Darlington Mar 14 '12 at 09:40

2 Answers2

19
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && [[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [UIScreen mainScreen].scale > 1)
{
    // new iPad
}
Noah Witherspoon
  • 57,021
  • 16
  • 130
  • 131
  • 8
    While technically correct, it will most likely return true for all the future iPads as well (which still may be just what you need). – Bartosz Ciechanowski Mar 13 '12 at 17:41
  • This answers the question, (detect Retina display). But if you really need to know device version, see [here](http://stackoverflow.com/questions/9638970/ios-the-new-ipad-uidevicehardware-hw-machine-codename) for an answer which identifies _all_ devices. – bobobobo Aug 24 '13 at 00:24
5

As other posters have answered, you should check for features rather than models. However, in the few obscure cases where you might want to identify a particular model, you can use the hw.machine sysctrl as follows. Note that if you can't identify the model, it's most likely because your code is running on a new model, so you should do something sensible in that case.

#include <sys/types.h>
#include <sys/sysctl.h>

// Determine the machine name, e.g. "iPhone1,1".
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0); // Get size of data to be returned.
char *name = malloc(size);
sysctlbyname("hw.machine", name, &size, NULL, 0);

NSString *machine = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];
free(name);

Now you can compare "machine" against known values. E.g., to detect iPad (March 2012) models:

if ([machine hasPrefix:@"iPad3,"]) NSLog(@"iPad (March 2012) detected");
bleater
  • 5,098
  • 50
  • 48
  • I already tested my app on iPad(Retina) emulator and it worked. I thought that I would have a problem because of the new resolution of the new iPad, but I was totally wrong. Thanks anyway, this can be useful for others. – António Mar 23 '12 at 09:51