How to differentiate between iphone4 and iphone 3
Asked Answered
J

9

43

I am trying to build a game for the iphone using cocos2d engine. I wanted to know how can I tell a difference whether the user is using iphone 4 or iphone 3 as I wanted to load hi-resolution graphics for the iphone4 and low-resolution for iphone 3. I know if I use @2x.png at the end of the image file name UIImage loads the hi-resolution image by itself if I am using an iphone 4 but for the game I am using cocos2d engine's CCSprite class to load the graphics.

I would really appreciate the reply.

Regards, Ankur

Joule answered 20/7, 2010 at 20:29 Comment(0)
G
123

You could check the scale of the screen.

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2){
    //iPhone 4
}
Greenwich answered 20/7, 2010 at 20:31 Comment(7)
Just be aware that scale is also available on the iPad in OS 3.2, not just the on iOS 4.Chem
Right, but the scale of an iPad isn't 2.Greenwich
Actually, the scale of the iPad is 2 when it's in 2x zoom mode.Chem
But, if you're on an iPad in 2x zoom, wouldn't serving up higher-res graphics be a nice bonus anyway?Upanchor
As noted in the comments above, this returns a false positive on the iPad 3.2 (but works correctly on iOS4.x devices).Beers
Like what Sickpea said. But, importantly to Henry Cooke: no -- there is no point in serving up high-res images on ipad when in 2x mode, as they won't be displayed at high res. That's part of the definition of 2x mode in 3.2Arjuna
This does not detect retina display on the new iPad. See my answer below.Contagious
C
12

For detecting retina display on all devices including the new iPad

    +(BOOL)isRetinaDisplay {
    // since we call this alot, cache it
    static CGFloat scale = 0.0;
    if (scale == 0.0) {
        // NOTE: In order to detect the Retina display reliably on all iOS devices,
        // you need to check if the device is running iOS4+ and if the 
        // [UIScreen mainScreen].scale property is equal to 2.0. 
        // You CANNOT assume a device is running iOS4+ if the scale property exists,
        // as the iPad 3.2 also contains this property.
        // On an iPad running iOS3.2, scale will return 1.0 in 1x mode, and 2.0
        // in 2x mode -- even though we know that device does not contain a Retina display.
        // Apple changed this behavior in iOS4.2 for the iPad: it returns 1.0 in both
        // 1x and 2x modes. You can test this yourself in the simulator.
        // I test for the -displayLinkWithTarget:selector: method on the main screen
        // which exists in iOS4.x but not iOS3.2, and then check the screen's scale:

        if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && 
            ([UIScreen mainScreen].scale == 2.0)) {
            scale = 2.0;
            return YES;
        } else {
            scale = 1.0;
            return NO;
        }   

    }
    return scale > 1.0;
}

Credit to: Adriano Paladini http://developer.appcelerator.com/question/133826/detecting-new-ipad-3-dpi-and-retina

Contagious answered 20/3, 2012 at 12:2 Comment(0)
H
5
- (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 stringWithCString:machine];  
    free(machine);  
    return platform;  
}  

- (NSString *) platformString  
{  
    NSString *platform = [self platform];  
    if ([platform isEqualToString:@"iPhone1,1"]) return @"Original iPhone";  
    if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";  
    if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3G[S]"; 
    if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";   
    return @"Unknown";  
}  
Hudspeth answered 31/1, 2011 at 3:37 Comment(0)
C
3

Despite what Apple's docs say, the UIScreen's scale property isn't just available in iOS4, it's also available in 3.2 on the iPad. This means it's probably an unreliable way to check which device you're on.

Instead, you should check if contentScaleFactor is available on your main window(or any UIView), and then check the scale value.

Chem answered 25/8, 2010 at 1:28 Comment(2)
unfortunately, contentScaleFactor is new in iOS 4 too, so it doesn't help with backwards compatibility any more than the scale property. I wonder if it changes from 1 to 2 on-the-fly if the user clicks the "2x" button on the iPad?Trehalose
It does in 3.2, so I figure it would in 4.2 as well, I haven't checked though.Chem
B
3

Checking the scale property is not sufficient, as on iPad 3.2 in 2x mode, the scale property exists and will return 2.0, but we know that device does NOT have a Retina display.

I've created at category on UIScreen to do this. For a more detailed explanation, see my answer to Detect Retina Display. Here's the code:

@interface UIScreen(ZBScreenRetinaAdditions)

// Returns YES if this is a Retina display.
- (BOOL)zb_isRetina;

@end

@implementation UIScreen(ZBScreenRetinaAdditions)

- (BOOL)zb_isRetina {
  return [self respondsToSelector:@selector(displayLinkWithTarget:selector:)] && (self.scale == 2.0);
}

@end

Usage example:

if ([UIScreen mainScreen] zb_isRetina) {
  // Retina display
}
Beers answered 9/1, 2011 at 20:21 Comment(2)
Just curious... why do you have ? YES : NO at the end? Not necessary in your code, right?Crater
You're right, it's unnecessary. This style is a bad habit I picked up from some examples when I was first learning Objective-C. Fixed.Beers
O
2

just adding my 2 cents :

I see what you are doing here, but binding this to a specific value like 2.0 is good for the moment, but what if for example next iPad got resolution bump like x1.5 ? For me anything that goes above 1.0 is kind of higher-than-normal display so I will load hi-res graphics. Does not matter much then if that is iPad,iPhone ....

Ob answered 31/1, 2011 at 3:33 Comment(0)
R
2

I know that the topic is a bit old now, but It might help some people. On Cocos2d you can load hi-resolution graphics for the iphone4 and low-resolution for iphone 3 using the -hd suffix on your files.

You just have to enable the retina display like this before:

// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director enableRetinaDisplay:YES] )
    CCLOG(@"Retina Display Not supported");

For more information read the documentation here: RetinaDisplay in cocos2d

Respectability answered 3/5, 2011 at 19:47 Comment(0)
A
2

import "UIScreen+Retina.h"

if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad){
    //IPAD        
    if ([[UIScreen mainScreen] isRetina]) {
        // IPAD 3 - Retina display
        bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPAD_HIGHRES;            
    }else{
        //iPAD 1/2
        bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPAD_LOWRES;        }
}else{
    //IPHONE
    if ([[UIScreen mainScreen] isRetina]) {
        // IPHONE 4/4s/5 - Retina display
        bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPHONE_HIGHRES;

    }else{
        //IPHONE (3.x)
        bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPHONE_LOWRES;

    }
}
Alumroot answered 8/3, 2012 at 11:1 Comment(0)
S
0

scale is available for iPad, however you can always use if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) to check whether it is iPad or iPhone/iTouch

Schadenfreude answered 27/9, 2011 at 18:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.