Detect Retina Display

IosIphoneRetina DisplayUiscreen

Ios Problem Overview


Does iOS SDK provides an easy way to check if the currentDevice has an high-resolution display (retina) ?

The best way I've found to do it now is :

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

Ios Solutions


Solution 1 - Ios

In order to detect the Retina display reliably on all iOS devices, you need to check if the device is running iOS4+ and if the [UIScreen mainScreen].scale property is equal to 2.0. You CANNOT assume a device is running iOS4+ if the scale property exists, as the iPad 3.2 also contains this property.

On an iPad running iOS3.2, scale will return 1.0 in 1x mode, and 2.0 in 2x mode -- even though we know that device does not contain a Retina display. Apple changed this behavior in iOS4.2 for the iPad: it returns 1.0 in both 1x and 2x modes. You can test this yourself in the simulator.

I test for the -displayLinkWithTarget:selector: method on the main screen which exists in iOS4.x but not iOS3.2, and then check the screen's scale:

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

Solution 2 - Ios

@sickp's answer is correct. Just to make things easier, add this line into your Shared.pch file:

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

Then in any file you can just do:

if(IS_RETINA)
{
   // etc..
}

Solution 3 - Ios

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

Solution 4 - Ios

Here is a handy swift extension:

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

Usage:

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

Original:

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

Usage:

if UIScreen.mainScreen().isRetina() {
 // your code
        }

Solution 5 - Ios

This snippet...

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

Will return... 0 for standard resolution iPhone/iPod touch, 1 for retina iPhone, 2 for standard resolution iPad, 3 for retina iPad.

Solution 6 - Ios

SSToolkit has a method that does this:

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

It is used in the following way:

[[UIScreen mainScreen] isRetinaDisplay];

Solution 7 - Ios

It always feels a bit dodgy to compare floating-point values for equality. I prefer going for either

[UIScreen mainScreen].scale > 1.0;

or

[UIScreen mainScreen].scale < 2.0;

Solution 8 - Ios

This is a riff on Matt MC's answer above. Just a category on 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

Solution 9 - Ios

Swift version of the answers above, with >= 2.0 scale so it includes iPhone 6+ and other future devices with higher-than-Retina scale:

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

Solution 10 - Ios

Just to combine the answer from @sickp and the following comment from @n13 I made this into a UIScreen category which seems to work nicely. The check is done the first time you call it and then saved for later calls.

@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

Might be useful to someone.

Solution 11 - Ios

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

Solution 12 - Ios

try this

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

Solution 13 - Ios

Modified version of primulaveris's for simplicity of most common use cases. I'm on swift 2.2 but it shouldn't matter.

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

Then simply use them like this

print(UIScreen.isRetina)
print(UIScreen.isRetinaHD)
print(UIScreen.screenScale)

Solution 14 - Ios

This worked for me

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPierre ValadeView Question on Stackoverflow
Solution 1 - IosTrashpandaView Answer on Stackoverflow
Solution 2 - IosMick ByrneView Answer on Stackoverflow
Solution 3 - IosManiView Answer on Stackoverflow
Solution 4 - IosprimulaverisView Answer on Stackoverflow
Solution 5 - IosPedroView Answer on Stackoverflow
Solution 6 - IosJorge PerezView Answer on Stackoverflow
Solution 7 - IosskahlertView Answer on Stackoverflow
Solution 8 - IosDan RosenstarkView Answer on Stackoverflow
Solution 9 - Ioscdf1982View Answer on Stackoverflow
Solution 10 - IosMatt McView Answer on Stackoverflow
Solution 11 - IosRoman SolodyashkinView Answer on Stackoverflow
Solution 12 - IosKARTHIK RAView Answer on Stackoverflow
Solution 13 - IosGregPView Answer on Stackoverflow
Solution 14 - IosMichael FretzView Answer on Stackoverflow