问题
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
}
回答1:
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
}
回答2:
@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..
}
回答3:
+(BOOL)iPhoneRetina{
return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0;
}
回答4:
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 >= 2.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
}
回答5:
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.
回答6:
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];
回答7:
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;
回答8:
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
回答9:
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
}
回答10:
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.
回答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:
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");
}
回答13:
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)
回答14:
This worked for me
if((UIScreen .mainScreen().scale) < 2.0)
{
NSLog("no retina");
}
else
{
NSLog("retina");
}
来源:https://stackoverflow.com/questions/3504173/detect-retina-display