Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect retina screen/iPhone 4 in iPhone SDK

In my application I am downloading some images from the web (from my server to be precise), in order to save some bandwith and especially memory on the phone, I provide them in two resolutions: 480x320 for the "old" iPhone series and in 960x640 for the iPhone 4 with the retina display. Now I need to be able to detect from within the app when it is running on a device that supports the retina screen. How could I do that?

I have been thinking about using the code snippet below which would return me a specific device identifier such as eg. "iPhone3", yet then I would be limiting the detection to the iPhone4 and would need to update that code for any subsequent device with a retina display.

size_t size;

// Set 'oldp' parameter to NULL to get the size of the data
// returned so we can allocate appropriate amount of space
sysctlbyname("hw.machine", NULL, &size, NULL, 0); 

// Allocate the space to store name
char *name = malloc(size);

// Get the platform name
sysctlbyname("hw.machine", name, &size, NULL, 0);

// Place name into a string
NSString *machine = [NSString stringWithCString:name];

Is there any better soution (maybe it is very obvious but I missed it)?

like image 884
Robin Avatar asked Jul 17 '10 18:07

Robin


3 Answers

Just did some reading on the official Apple Developers Forums and the issues has been discussed in length there. The best way to me seems to be the use of the scale property of UIScreen. Although it is only available in iOS 4 and later, it will tell you everything you need to know and will most likely play an even more important role in the future (already noticed that the iPad's screen resolution of 1024x768 is exactly 32/15 * 480x320?).

UIScreen.mainScreen.scale

If you have yet another idea feel free to post it :)

like image 92
Robin Avatar answered Nov 04 '22 14:11

Robin


Here is some code to do it the right way for both iOS 3.x and 4.x:

BOOL hasHighResScreen = NO;
if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
    CGFloat scale = [[UIScreen mainScreen] scale];
    if (scale > 1.0) {
        hasHighResScreen = YES;
    }
}
like image 23
Scott Gustafson Avatar answered Nov 04 '22 12:11

Scott Gustafson


A little update on answer by Scott Gustafson:

If we need to distinguish between iPad/Retina/iphone:

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 
    {
        CGFloat scale = [[UIScreen mainScreen] scale];

           if (scale > 1.0) 
           {
                //iPad retina screen
           }  
           else
           {
                //iPad screen
           }
    } 
    else
    {
         if ([UIScreen instancesRespondToSelector:@selector(scale)]) 
         {
               CGFloat scale = [[UIScreen mainScreen] scale];

               if (scale > 1.0) 
               {
                    if([[ UIScreen mainScreen ] bounds ].size.height == 568)
                    {
                        //iphone 5
                    }
                    else
                    {
                        //iphone retina screen
                    }
               }
               else
               {
                    //iphone screen
               }
         }
    }
like image 13
Guntis Treulands Avatar answered Nov 04 '22 12:11

Guntis Treulands