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

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

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) {
         // 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;
}

其他回答

primulaveris's的修改版本,以简化最常见的用例。我用的是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)

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

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

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

可能对某人有用。

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

在运行iOS3.2的iPad上,比例在1倍模式下将返回1.0,在2倍模式下将返回2.0——尽管我们知道该设备不包含视网膜显示屏。苹果在iPad的iOS4.2中改变了这一行为:它在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
}