在iPhone SDK中检测视网膜屏幕/ iPhone 4

时间:2010-07-17 18:32:24

标签: iphone cocoa-touch iphone-4

在我的应用程序中,我正在从网络上下载一些图像(从我的服务器上来说是精确的),为了节省一些带宽,尤其是手机内存,我提供两种分辨率:480x320用于“旧”iPhone系列和960x640适用于带有视网膜显示屏的iPhone 4。现在,我需要能够在应用程序中检测它何时在支持视网膜屏幕的设备上运行。我怎么能这样做?

我一直在考虑使用下面的代码片段,它会返回一个特定的设备标识符,例如。 “iPhone3”,然后我会将检测限制在iPhone4上,并且需要为具有视网膜显示器的任何后续设备更新该代码。

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

有没有更好的选择(也许这很明显,但我错过了它)?

11 个答案:

答案 0 :(得分:32)

刚刚在官方Apple开发者论坛上做了一些阅读,并且已经在那里详细讨论了这些问题。对我而言,最好的方法似乎是使用scale的{​​{1}}属性。虽然它只在UIScreen及以后提供,它会告诉你需要知道的一切,并且很可能在未来发挥更重要的作用(已经注意到iPad的屏幕分辨率为1024x768正好是32 / 15 * 480x320?)。

iOS 4

如果您还有其他想法可以随意发布:)

答案 1 :(得分:23)

以下是一些代码,以正确的方式为iOS 3.x和4.x执行:

BOOL hasHighResScreen = NO;
if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
    CGFloat scale = [[UIScreen mainScreen] scale];
    if (scale > 1.0) {
        hasHighResScreen = YES;
    }
}

答案 2 :(得分:13)

Scott Gustafson对答案的一点回应:

如果我们需要区分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
               }
         }
    }

答案 3 :(得分:5)

通过这种方式我得到了真正的屏幕尺寸(以像素为单位):

UIScreen *MainScreen = [UIScreen mainScreen];
UIScreenMode *ScreenMode = [MainScreen currentMode];
CGSize Size = [ScreenMode size]; // <--- Real screen size

答案 4 :(得分:3)

- (BOOL)isRetina {

    BOOL isRetina = NO;

    if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
        CGFloat scale = [[UIScreen mainScreen] scale];
        if (scale > 1.0) {
            isRetina = YES;
        }
    }

    return isRetina;
}


- (CGSize)sizeInPixels {

    CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
    CGSize screenSize = CGSizeMake(appFrame.size.width, appFrame.size.height);

    return [self isRetina] ? CGSizeMake(screenSize.width * 2, screenSize.height * 2) : screenSize;
}

答案 5 :(得分:1)

跟罗宾回答。另一个注意事项:如果确实需要检查设备名称,只需使用UIDevice上的方法即可。

[[UIDevice currentDevice] model];
[[UIDevice currentDevice] systemName];
[[UIDevice currentDevice] systemVersion];

答案 6 :(得分:1)

UIScreen *MainScreen = [UIScreen mainScreen];
UIScreenMode *ScreenMode = [MainScreen currentMode];
CGSize Size = [ScreenMode size]; // <--- Real screen size

答案 7 :(得分:1)

对于那些只想复制/粘贴如何检测iphone / iphone_retina / ipad / ipad_retina的人来说,这是我在阅读这个帖子后最终做的事情。受到Guntis Treulands贡献的深刻启发,后者反过来扩展了Scott Gustafsons的答案。

- (NSString *) yesButWhichDeviceIsIt {    
    BOOL hasRetina = NO;
    if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
        CGFloat scale = [[UIScreen mainScreen] scale];
        if (scale > 1.0) {
            hasRetina = YES;
        }
    }
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        if (hasRetina) {
            return @"iPad retina";
        } else {
            return @"iPad";
        }
    } else {
        if (hasRetina) {
            return @"iPhone retina";
        } else {
            return @"iPhone";
        }        
    }
}

答案 8 :(得分:0)

如果您使用的是Cocos2d,请尝试以下操作:

[[CCDirector sharedDirector] winSizeInPixels];

它将返回包含属性CGSizewidth的{​​{1}}。

答案 9 :(得分:0)

+(BOOL)Retina{
        return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0; }

答案 10 :(得分:-1)

虽然您已经选择了答案,但在专门处理图像时有一种更简单的方法,所以我也会提到它。

如果在两个尺寸(320x480和640x960)的捆绑中包含两个图像,并在后一个图像的文件名末尾添加“@ 2x”,[UIImage imageNamed:]将自动为旧设备选择较小的图像如果您不使用图像后缀,则可以使用带有视网膜显示屏的设备的2倍。例:

2张名为@“image.png”和@“image@2x.png”的图片,均包含在应用套装中。

然后致电:

[UIImage imageNamed:@"image"];

这也是应用程序图标和加载屏幕的工作方式。