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

发布于 2024-09-09 21:45:41 字数 752 浏览 8 评论 0原文

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

我一直在考虑使用下面的代码片段,它会返回一个特定的设备标识符,例如。 “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];

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

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)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

黄昏下泛黄的笔记 2024-09-16 21:45:41

刚刚在官方苹果开发者论坛上阅读了一些内容,这些问题已经在那里进行了详细讨论。对我来说最好的方法似乎是使用 UIScreenscale 属性。虽然它仅在 iOS 4 及更高版本中可用,但它会告诉您需要了解的一切,并且很可能在未来发挥更重要的作用(已经注意到 iPad 的屏幕分辨率为 1024x768正好是 32/15 * 480x320?)。

UIScreen.mainScreen.scale

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

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 :)

日久见人心 2024-09-16 21:45:41

下面是一些代码,可以在 iOS 3.x 和 4.x 上以正确的方式执行此操作:

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

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;
    }
}
つ可否回来 2024-09-16 21:45:41

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
               }
         }
    }

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
               }
         }
    }
梦一生花开无言 2024-09-16 21:45:41

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

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

I get real screen size (in pixels) by this way:

UIScreen *MainScreen = [UIScreen mainScreen];
UIScreenMode *ScreenMode = [MainScreen currentMode];
CGSize Size = [ScreenMode size]; // <--- Real screen size
柠栀 2024-09-16 21:45:41
- (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;
}
- (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;
}
楠木可依 2024-09-16 21:45:41

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

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

Go with Robin's answer. One other note: if you do need to check the device name, just use the methods on UIDevice.

[[UIDevice currentDevice] model];
[[UIDevice currentDevice] systemName];
[[UIDevice currentDevice] systemVersion];
潦草背影 2024-09-16 21:45:41
UIScreen *MainScreen = [UIScreen mainScreen];
UIScreenMode *ScreenMode = [MainScreen currentMode];
CGSize Size = [ScreenMode size]; // <--- Real screen size
UIScreen *MainScreen = [UIScreen mainScreen];
UIScreenMode *ScreenMode = [MainScreen currentMode];
CGSize Size = [ScreenMode size]; // <--- Real screen size
挖个坑埋了你 2024-09-16 21:45:41

对于那些只想复制/粘贴如何检测 iphone/iphone_retina/ipad/ipad_retina 的人来说,这就是我在阅读此线程后最终所做的事情。深受 Guntis Treulands 贡献的启发,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";
        }        
    }
}

And for those who just want to copy/paste how to detect iphone/iphone_retina/ipad/ipad_retina, here's what I ended up doing after reading this thread. Heavily inspired by Guntis Treulands' contribution, who in turn expanded upon Scott Gustafsons answer.

- (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";
        }        
    }
}
小草泠泠 2024-09-16 21:45:41

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

[[CCDirector sharedDirector] winSizeInPixels];

它将返回一个 CGSize,其属性为 width 和 <代码>高度。

If you're using Cocos2d, try the following:

[[CCDirector sharedDirector] winSizeInPixels];

It will return a CGSize with properties width and height.

薄暮涼年 2024-09-16 21:45:41
+(BOOL)Retina{
        return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0; }
+(BOOL)Retina{
        return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0; }
憧憬巴黎街头的黎明 2024-09-16 21:45:41

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

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

2 个名为 @"image.png" 和 @"[电子邮件受保护]< 的图像/a>”,两者都包含在应用程序包中。

然后调用:

[UIImage imageNamed:@"image"];

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

Although you've already selected an answer, there is a much easier way when specifically dealing with images so I'll mention it as well.

If you include two images in your bundle of the two sizes (320x480 and 640x960) and you append "@2x" at the end of the latter image's filename, [UIImage imageNamed:] will automagically pick the smaller image for older devices and the 2x for devices with a retina display, provided you leave off the image suffix. Ex.:

2 images named @"image.png" and @"[email protected]", both included in the app bundle.

Then call:

[UIImage imageNamed:@"image"];

This is also how app icons and the loading screen work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文