iOS SDK是否提供了一种简单的方法来检查currentDevice是否具有高分辨率显示(视网膜)?检测视网膜显示
我发现现在做到这一点的最好办法是:
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) {
// RETINA DISPLAY
}
iOS SDK是否提供了一种简单的方法来检查currentDevice是否具有高分辨率显示(视网膜)?检测视网膜显示
我发现现在做到这一点的最好办法是:
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) {
// RETINA DISPLAY
}
为了可靠地检测在所有iOS设备的Retina显示屏,你需要检查设备运行iOS4的+,如果[UIScreen mainScreen].scale
属性等于2.0。如果scale
属性存在,则不能假定设备正在运行iOS4 +,因为iPad 3.2也包含此属性。
在运行iOS3.2的iPad上,缩放将在1x模式下返回1.0,在2x模式下返回2.0 - 即使我们知道设备不包含Retina显示屏。 Apple在iOS4.2中为iPad改变了这种行为:它在1x和2x模式下均返回1.0。你可以在模拟器中自己测试一下。
我测试存在于iOS4.x但不iOS3.2在主屏幕上的-displayLinkWithTarget:selector:
方法,然后检查屏幕的规模:
if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] &&
([UIScreen mainScreen].scale == 2.0)) {
// Retina display
} else {
// non-Retina display
}
+(BOOL)iPhoneRetina{
return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0;
}
为什么'?1:0'?这不仅仅是重申已经在表达式的布尔部分中计算出的内容吗? – d11wtq 2013-02-04 04:58:10
这个片段...
int d = 0; // standard display
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2.0) {
d = 1; // is retina display
}
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
d += 2;
}
将返回... 0的标准分辨率的iPhone/iPod touch上, 1视网膜iPhone, 2标准分辨率iPad, 3用于视网膜iPad。
SSToolkit有做这个的方法:
http://sstoolk.it/documentation/Categories/UIScreen(SSToolkitAdditions).html
它在使用方式如下:
[[UIScreen mainScreen] isRetinaDisplay];
SSToolKit中的这个特殊用法已被SAMCategories取代:[[UIScreen mainScreen] sam_isRetina] – tempire 2014-03-26 06:35:30
@ sickp的答案是正确的。只是为了让事情变得更容易,添加此行到您的Shared.pch文件:任何文件,你可以做
#define IS_RETINA ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale >= 2.0))
然后:
if(IS_RETINA)
{
// etc..
}
非常好的结构化答案。谢谢 – 2014-10-16 09:25:27
这在模拟器上不起作用。是因为respondsToSelector吗?模拟器不响应选择器? – arniotaki 2015-02-19 08:27:52
太棒了!但是,如果你想考虑iPhone 6 Plus,你应该检查scale> = 2.0。 – 2015-04-15 01:25:32
它,总觉得有点不可靠,比较浮点平等的价值观。 我宁愿去为任何
[UIScreen mainScreen].scale > 1.0;
或
[UIScreen mainScreen].scale < 2.0;
比较两个浮点值的相等“感觉不好”,因为它们在计算之后可能与整数值略有不同。但与< or >相比,在这些情况下也是如此狡猾。然而,在这种情况下,根本不可能有任何规模不完全是1.0或2.0,因为它是硬件定义的。 – fishinear 2013-03-22 17:19:34
@fishinear建议,最好使用'isRetina = [UIScreen mainScreen] .scale> 1.95'。当@ 4x出现时,这也会有弹性的好处:) – 2013-08-06 15:44:07
我强烈反对。在不需要时执行此操作会使代码不易读。关于未来证明的观点可能有其合理性,但我怀疑我们很快就会有@ 4x的屏幕(如果有的话)。 – 2013-08-16 17:03:07
刚刚从@sickp答案结合起来,从@ N13这样的评论我做这个成UIScreen范畴,这似乎很好地工作。该检查在您第一次打电话时完成,然后保存以供稍后调用。
@interface UIScreen (RetinaCheck)
+ (BOOL)retinaScreen;
@end
static BOOL isRetinaScreen = NO;
static BOOL didRetinaCheck = NO;
@implementation UIScreen (RetinaCheck)
+ (BOOL)retinaScreen
{
if (!didRetinaCheck) {
isRetinaScreen = ([[self mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] &&
([self mainScreen].scale == 2.0));
didRetinaCheck = YES;
}
return isRetinaScreen;
}
@end
可能对某人有用。
感谢您的缓存代码。我唯一的建议是使这个'(Util)'而不是'(RetinaCheck)'......也许不那么清楚,但它适用于其他用途。 另外我会命名方法'isRetinaDisplay'或以'is'开头的东西,但也许我从来没有理解Obj-C的指导原则。 另外,我是'> 1.0的粉丝,但谁知道什么会有意义的前进。 – 2013-11-13 20:28:13
这是马特MC的回答上面的一段。只是UIScreen
的一个类别。
#import "UIScreen+Util.h"
@implementation UIScreen (Util)
+ (BOOL) isRetinaDisplay {
static BOOL retina = NO;
static BOOL alreadyChecked = NO;
if (!alreadyChecked) {
UIScreen *mainScreen = self.mainScreen;
if (mainScreen) {
retina = mainScreen.scale > 1.0;
alreadyChecked = YES;
}
}
return retina;
}
@end
我怀疑'alreadyChecked'的缓存是无偿的,但没关系。 – 2013-11-28 20:55:48
多线程情况怎么样? – 2014-04-22 12:18:43
@NikolayShubenkov这就是为什么我已经设置了最后检查。在最坏的情况下,你运行代码来检查额外的一两次。 – 2014-04-23 01:06:20
尝试高于此
if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] &&
([UIScreen mainScreen].scale == 2.0))
{
// Retina display
NSLog(@"---------------Retina display");
} else {
// non-Retina display
NSLog(@"---------------non-Retina display");
}
// .h
UIKIT_EXTERN bool isRetinaDisplay();
// .m
bool isRetinaDisplay()
{
static bool flag;
#ifdef __BLOCKS__
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
{
flag = [[UIScreen mainScreen] scale] > 1.0;
}
else
{
flag = false;
}
});
#else
static bool onceToken;
if(onceToken == false)
{
onceToken = true;
if([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
{
flag = [[UIScreen mainScreen] scale] > 1.0;
}
else
{
flag = false;
}
}
#endif
return flag;
}
我认为最好的解决方案。 – 2014-04-22 12:20:01
的答案夫特版本,> = 2.0规模所以它包括iPhone 6+和其他未来的设备与规模比-视网膜更高:
if UIScreen.mainScreen().respondsToSelector(Selector("scale")) && UIScreen.mainScreen().scale >= 2.0 {
// code executed only on Retina device
}
这里是一个方便快捷的扩展:
extension UIScreen {
public func isRetina() -> Bool {
return screenScale() >= 2.0
}
public func isRetinaHD() -> Bool {
return screenScale() >= 3.0
}
private func screenScale() -> CGFloat? {
if UIScreen.mainScreen().respondsToSelector(Selector("scale")) {
return UIScreen.mainScreen().scale
}
return nil
}
}
用法:primulaveris年代为最常见的使用情况简单
if UIScreen.mainScreen().isRetina() {
// your code
}
改良版。我在迅速2.2,但它应该没关系。
extension UIScreen {
static var isRetina: Bool {
return screenScale >= 2.0
}
static var isRetinaHD: Bool {
return screenScale >= 3.0
}
static var screenScale:CGFloat {
return UIScreen.mainScreen().scale
}
}
然后只需用他们喜欢这个
print(UIScreen.isRetina)
print(UIScreen.isRetinaHD)
print(UIScreen.screenScale)
这为我工作
if((UIScreen .mainScreen().scale) < 2.0)
{
NSLog("no retina");
}
else
{
NSLog("retina");
}
出于好奇 - 你在做什么,当你发现其他的显示器不是显示较大的版本的艺术作品? – mbehan 2010-08-17 15:35:17
可能重复的[如何区分iphone4和iphone 3](http://stackoverflow.com/questions/3294100/how-to-differentiate-between-iphone4-and-iphone-3) – 2010-08-17 17:09:45
@mbehan:我有一个TTImageView(请参阅Three20框架),我想给出图像的高分辨率URL。 – 2010-08-18 10:05:26