iOS SDK是否提供一种简便的方法来检查currentDevice是否具有高分辨率显示器(视网膜)?
我发现现在最好的方法是:
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) {
// RETINA DISPLAY
}
iOS SDK是否提供一种简便的方法来检查currentDevice是否具有高分辨率显示器(视网膜)?
我发现现在最好的方法是:
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) {
// RETINA DISPLAY
}
Answers:
为了在所有iOS设备上可靠地检测Retina显示屏,您需要检查设备是否正在运行iOS4 +,以及该[UIScreen mainScreen].scale
属性是否等于2.0。如果该scale
属性存在,则不能假定设备正在运行iOS4 + ,因为iPad 3.2也包含此属性。
在运行iOS3.2的iPad上,scale将在1x模式下返回1.0,在2x模式下返回2.0-即使我们知道该设备不包含Retina显示屏。苹果在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
}
[UIDevice currentDevice].systemVersion]
。在这种情况下,应该是NSString *currentSystemVersion = [[UIDevice currentDevice] systemVersion]; return [currentSystemVersion compare:version options:NSNumericSearch];
@sickp的答案是正确的。为了使事情变得简单,请将以下行添加到您的Shared.pch文件中:
#define IS_RETINA ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale >= 2.0))
然后,您可以在任何文件中执行以下操作:
if(IS_RETINA)
{
// etc..
}
这是一个便捷的扩展:
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
}
这个片段...
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。
SSToolkit具有执行此操作的方法:
http://sstoolk.it/documentation/Categories/UIScreen(SSToolkitAdditions).html
它以以下方式使用:
[[UIScreen mainScreen] isRetinaDisplay];
比较浮点值是否相等总是让人有些疑惑。我更喜欢去
[UIScreen mainScreen].scale > 1.0;
要么
[UIScreen mainScreen].scale < 2.0;
isRetina = [UIScreen mainScreen].scale > 1.95
。这也将具有抵御@ 4x出现的时间的好处:)
这是对马特·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
alreadyChecked
是免费的,但这很好。
只是为了结合@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
对某人可能有用。
(Util)
替代,而不是(RetinaCheck)
...可能不太清楚,但它可用于其他用途。另外,我想说一下方法isRetinaDisplay
或以开头的东西is
,但是也许我从来没有理解过Obj-C的指南。另外,我还是的粉丝,> 1.0
但谁知道前进的意义。
// .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的修改版本,用于简化大多数常见用例。我使用的是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)