23

在我的应用程序中,我正在从网络(准确地说是从我的服务器)下载一些图像,为了节省一些带宽,尤其是手机上的内存,我以两种分辨率提供它们:480x320 用于“旧”iPhone 系列和960x640 适用于配备 Retina 显示屏的 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];

有没有更好的解决方案(也许很明显,但我错过了)?

4

11 回答 11

32

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

UIScreen.mainScreen.scale

如果您还有其他想法,请随时发布:)

于 2010-07-17T19:05:46.800 回答
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;
    }
}
于 2010-08-28T02:36:34.093 回答
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
               }
         }
    }
于 2011-09-30T07:12:09.640 回答
5

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

UIScreen *MainScreen = [UIScreen mainScreen];
UIScreenMode *ScreenMode = [MainScreen currentMode];
CGSize Size = [ScreenMode size]; // <--- Real screen size
于 2010-11-06T17:51:07.190 回答
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;
}
于 2012-07-05T13:49:56.467 回答
1

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

[[UIDevice currentDevice] model];
[[UIDevice currentDevice] systemName];
[[UIDevice currentDevice] systemVersion];
于 2010-08-14T22:13:32.630 回答
1
UIScreen *MainScreen = [UIScreen mainScreen];
UIScreenMode *ScreenMode = [MainScreen currentMode];
CGSize Size = [ScreenMode size]; // <--- Real screen size
于 2010-11-26T11:34:50.620 回答
1

对于那些只想复制/粘贴如何检测 iphone/iphone_retina/ipad/ipad_retina 的人来说,这就是我在阅读此线程后最终所做的事情。深受 Guntis Treulands 贡献的启发,后者又扩展了 Scott Gustafson 的回答。

- (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";
        }        
    }
}
于 2012-05-07T19:01:15.453 回答
0

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

[[CCDirector sharedDirector] winSizeInPixels];

它将返回一个CGSize带有属性widthheight.

于 2011-06-15T01:45:06.477 回答
0
+(BOOL)Retina{
        return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0; }
于 2012-05-23T11:03:43.680 回答
-1

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

如果您在捆绑包中包含两种尺寸(320x480 和 640x960)的两个图像,并在后一个图像的文件名末尾附加“@2x”,[UIImage imageNamed:] 将自动为旧设备选择较小的图像,而 2x对于具有视网膜显示屏的设备,只要您去掉图像后缀。前任。:

2 个名为 @"image.png" 和 @"image@2x.png" 的图像,均包含在应用程序包中。

然后调用:

[UIImage imageNamed:@"image"];

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

于 2011-12-20T04:40:56.473 回答