2010-07-17 77 views
24

在我的应用程序中,我从网上下载一些图像(从我的服务器到精确),为了节省一些带宽,特别是手机内存,我提供了两个分辨率:“旧”iPhone系列为480x320,视网膜显示屏为iPhone 4的960x640。现在,我需要能够在应用程序内运行支持视网膜屏幕的设备时进行检测。我怎么能这样做?在iPhone SDK中检测视网膜屏幕/ 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]; 

有没有更好的饮料(可能它很明显,但我错过了)?

回答

32

刚刚在官方的Apple开发者论坛上做了一些阅读,并且已经在那里讨论了这些问题。对我来说最好的办法似乎是使用UIScreenscale财产。虽然只有在iOS 4及以后才有,但它会告诉你所有你需要知道的事情,并且很可能在未来扮演更重要的角色(已经注意到,1024x768的屏幕分辨率正好是32/15 * 480x320? )。

UIScreen.mainScreen.scale 

如果您还没有另一个想法随意张贴:)

+0

这是做它的正确途径。 – Elfred 2010-07-17 19:08:02

+2

是的,使用这个,千万不要试图查询你正在运行的设备,它只会以痛苦结束。 – 2010-07-17 23:25:09

+0

这是正确的方法,因为您不想为iPhone 4编写条件代码,而是为具有不同比例/分辨率的显示器编写条件代码。谁知道iPod什么时候能够获得视网膜治疗。 – FelixLam 2010-07-18 09:38:02

1

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

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

为读者练习:为什么检测设备(而不是能力)总是一个坏主意。 – 2011-05-30 22:41:24

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; 
    } 
} 
+0

只要注意,如果它以2x开头,这也可能会成为iPad的“iphone模拟器”模式,这可能是也可能不是你想要的。 – 2010-09-29 22:29:42

+2

iPad上的“iphone模拟器”有2x解决方案吗? – joelsand 2011-01-17 15:33:35

5

我得到真正的屏幕尺寸(像素):

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

如果你使用cocos2d的,请尝试以下操作:

[[CCDirector sharedDirector] winSizeInPixels];

它将返回CGSize与属性widthheight

15

在回答一个小更新由斯科特·古斯塔夫森:

如果我们需要的iPad /视网膜/ 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 
       } 
     } 
    } 
-1

虽然你已经选择了一个答案,有一个更容易当专门处理图像时,我会提及它。

如果您在两种尺寸(320x480和640x960)的包中包含两个图像,并且在后一图像的文件名末尾附加了“@ 2x”,则[UIImage imageNamed:]会自动为较旧的图像选择较小的图像设备和2倍的设备与视网膜显示器,只要你离开图像后缀。例如:

2个图像名为@“image.png”和@“[email protected]”,都包含在应用程序包中。

然后调用:

[UIImage imageNamed:@"image"]; 

这也是如何应用程序图标和加载屏幕工作。

+0

-1:你没看过帖子的开头......?引用一句,“在我的应用程序中,我**正在从网上下载一些图片**” – 2013-05-17 05:01:23

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"; 
     }   
    } 
} 
0
+(BOOL)Retina{ 
     return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0; } 
+2

正常的可可命名实践将决定用小写字母命名该方法。 – Monolo 2012-07-15 11:51:23

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