Обнаружение Retina Display

Предоставляет ли IOS SDK простой способ проверить, имеет ли текущий дисплей экран высокого разрешения (сетчатка)?

Лучший способ, которым я нашел это сейчас:

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

Ответ 1

Для надежного обнаружения дисплея Retina на всех устройствах iOS вам нужно проверить, работает ли устройство iOS4 +, и если свойство [UIScreen mainScreen].scale равно 2.0. Вы НЕ МОЖЕТЕ предположить, что на устройстве работает iOS4 +, если свойство scale существует, поскольку iPad 3.2 также содержит это свойство.

На iPad под управлением iOS3.2 масштабирование вернет 1.0 в 1x режиме и 2.0 в 2x режиме - хотя мы знаем, что устройство не содержит дисплей Retina. Apple изменила это поведение в iOS4.2 для iPad: он возвращает 1.0 в режимах 1x и 2x. Вы можете проверить это самостоятельно в симуляторе.

Я тестирую метод -displayLinkWithTarget:selector: на основном экране, который существует в iOS4.x, но не iOS3.2, а затем проверяет масштаб экрана:

if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] &&
    ([UIScreen mainScreen].scale == 2.0)) {
  // Retina display
} else {
  // non-Retina display
}

Ответ 2

@sickp ответ правильный. Чтобы упростить задачу, добавьте эту строку в свой файл Shared.pch:

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

Затем в любом файле вы можете просто:

if(IS_RETINA)
{
   // etc..
}

Ответ 3

+(BOOL)iPhoneRetina{
    return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0;
}

Ответ 4

Этот фрагмент...

    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.

Ответ 6

Вот удобное быстрое расширение:

Обновление для 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 >= 2.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
        }

Ответ 7

Кажется, что для равенства равнозначно сравнивать значения с плавающей запятой. Я предпочитаю использовать либо

[UIScreen mainScreen].scale > 1.0;

или

[UIScreen mainScreen].scale < 2.0;

Ответ 8

Это рифф на Мэтт-Метр выше. Просто категория на 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

Ответ 9

Быстрая версия ответов выше, с шкалой >= 2.0, поэтому она включает iPhone 6+ и другие будущие устройства с шкалой более высокой, чем сетчатка:

 if UIScreen.mainScreen().respondsToSelector(Selector("scale")) && UIScreen.mainScreen().scale >= 2.0 {
    // code executed only on Retina device
}

Ответ 10

Просто чтобы совместить ответ с @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

Может быть полезно кому-то.

Ответ 11

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

Ответ 12

попробуйте это

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

Ответ 13

Модифицированная версия primulaveris для простоты большинства распространенных случаев использования. Я на скорости 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)

Ответ 14

Это сработало для меня

if((UIScreen .mainScreen().scale) < 2.0)
{
    NSLog("no retina");
}
else
{
    NSLog("retina");
}