225

iOS SDK 是否提供了一种简单的方法来检查 currentDevice 是否具有高分辨率显示器(视网膜)?

我现在发现的最好方法是:

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) {
         // RETINA DISPLAY
    }
4

14 回答 14

296

为了在所有 iOS 设备上可靠地检测 Retina 显示,您需要检查设备是否运行 iOS4+ 以及该[UIScreen mainScreen].scale属性是否等于 2.0。如果该属性存在,您不能假设设备正在运行 iOS4+ scale,因为 iPad 3.2 也包含该属性。

在运行 iOS3.2 的 iPad 上,缩放将在 1x 模式下返回 1.0,在 2x 模式下返回 2.0——即使我们知道该设备不包含 Retina 显示屏。Apple 在 iOS4.2 中为 iPad 改变了这种行为:它在 1x 和 2x 模式下都返回 1.0。您可以在模拟器中自行测试。

我测试了-displayLinkWithTarget:selector:iOS4.x中存在但iOS3.2中不存在的主屏幕上的方法,然后检查屏幕的比例:

if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] &&
    ([UIScreen mainScreen].scale == 2.0)) {
  // Retina display
} else {
  // non-Retina display
}
于 2011-01-09T20:11:07.477 回答
81

@sickp 的回答是正确的。只是为了让事情更容易,将此行添加到您的 Shared.pch 文件中:

#define IS_RETINA ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale >= 2.0))

然后在任何文件中你都可以这样做:

if(IS_RETINA)
{
   // etc..
}
于 2013-02-21T02:58:06.800 回答
20
+(BOOL)iPhoneRetina{
    return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0;
}
于 2012-06-11T05:16:35.173 回答
10

这是一个方便的快速扩展:

Swift v5 更新:

extension UIScreen {

    public var isRetina: Bool {
        guard let scale = screenScale else {
            return false
        }
        return scale >= 2.0
    }

    public var isRetinaHD: Bool {
        guard let scale = screenScale else {
            return false
        }
        return scale >= 3.0
    }

    private var screenScale: CGFloat? {
        guard UIScreen.main.responds(to: #selector(getter: scale)) else {
            return nil
        }
        return UIScreen.main.scale
    }
}

用法:

if UIScreen.main.isRetina {
    // Your code
}

原来的:

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

用法:

if UIScreen.mainScreen().isRetina() {
 // your code
        }
于 2016-01-15T12:21:39.970 回答
6

SSToolkit 有一个方法可以做到这一点:

http://sstoolk.it/documentation/Categories/UIScreen(SSToolkitAdditions).html

它以下列方式使用:

[[UIScreen mainScreen] isRetinaDisplay];
于 2012-11-09T09:25:53.087 回答
6

这个片段...

    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。

于 2012-08-22T22:32:09.910 回答
6

比较浮点值是否相等总是让人觉得有点狡猾。我更喜欢去

[UIScreen mainScreen].scale > 1.0;

或者

[UIScreen mainScreen].scale < 2.0;
于 2013-03-07T10:40:54.363 回答
2

这是对马特 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
于 2013-11-13T21:29:29.653 回答
2

上述答案的 Swift 版本,比例 >= 2.0,因此它包括 iPhone 6+ 和其他具有高于 Retina 比例的未来设备:

 if UIScreen.mainScreen().respondsToSelector(Selector("scale")) && UIScreen.mainScreen().scale >= 2.0 {
    // code executed only on Retina device
}
于 2015-07-11T20:08:02.390 回答
1

只是为了将@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

可能对某人有用。

于 2013-07-04T20:49:43.680 回答
1
// .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-11T20:15:55.223 回答
0

尝试这个

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");
}
于 2014-01-08T06:57:01.150 回答
0

primulaveris 的修改版本,以简化最常见的用例。我在 swift 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)
于 2016-04-12T13:20:07.957 回答
0

这对我有用

if((UIScreen .mainScreen().scale) < 2.0)
{
    NSLog("no retina");
}
else
{
    NSLog("retina");
}
于 2016-05-12T07:10:04.607 回答