如何检测iPhone 5(宽屏设备)?

How to detect iPhone 5 (widescreen devices)?

提问人:Finn Gaida 提问时间:9/16/2012 最后编辑:General GrievanceFinn Gaida 更新时间:6/9/2023 访问量:155942

问:

我刚刚升级到 Xcode 4.5 GM,发现您现在可以在情节提要中将“4 英寸视网膜”大小应用于视图控制器。

现在,如果我想创建一个同时在 iPhone 4 和 iPhone 5 上运行的应用程序,我当然必须为每个窗口构建两次,但我还必须检测用户使用的是 3.5 英寸还是 4 英寸屏幕的 iPhone,然后应用视图。

我应该怎么做?

iOS Objective-C iPhone 屏幕

评论

2赞 Till 9/16/2012
您不必将每个“窗口”构建两次。只有那些应该与屏幕尺寸完全匹配的才需要重新布局。解决方案似乎相当明显,只需检查窗口尺寸并根据返回的大小添加案例决策即可。
1赞 Finn Gaida 9/16/2012
嗯,基本上这是真的,但我想以一种完全不同的方式使用额外的屏幕尺寸,就像你对横向屏幕所做的那样。
0赞 ios_av 4/9/2013
检查此 URL:stackoverflow.com/questions/4779221/...
0赞 hfossli 11/2/2014
这个问题是否应该根据新设备进行更新?例如,“如何通过屏幕尺寸检测iOS设备”?

答:

467赞 Macmade 9/16/2012 #1

首先,不应重新生成所有视图以适应新屏幕,也不应为不同的屏幕大小使用不同的视图。

使用 iOS 的自动调整大小功能,以便您的视图可以调整和调整任何屏幕尺寸。

这不是很难,请阅读一些有关这方面的文档。这将为您节省大量时间。

iOS 6 还提供了相关的新功能。
请务必阅读 Apple 开发者网站上的 iOS 6 API 更新日志
并检查新的 iOS 6 自动布局功能。

也就是说,如果你真的需要检测iPhone 5,你可以简单地依靠屏幕尺寸

[ [ UIScreen mainScreen ] bounds ].size.height

iPhone 5的屏幕高度为568。
你可以想象一个宏来简化所有这些:

#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

在这里使用 with the epsilon 是为了防止在比较浮点时出现精度误差,正如 H2CO3 的评论中所指出的那样。fabs

因此,从现在开始,您可以在标准的 if/else 语句中使用它:

if( IS_IPHONE_5 )
{}
else
{}

编辑 - 更好的检测

正如一些人所说,这只能检测到宽屏,而不是实际的iPhone 5。

iPod touch的下一个版本可能也会有这样的屏幕,因此我们可能会使用另一组宏。

让我们重命名原始宏:IS_WIDESCREEN

#define IS_WIDESCREEN ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

让我们添加模型检测宏:

#define IS_IPHONE ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPhone" ] )
#define IS_IPOD   ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPod touch" ] )

这样,我们可以确保我们拥有 iPhone 型号宽屏,并且可以重新定义宏:IS_IPHONE_5

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

另请注意,如@LearnCocos2D所述,如果应用程序未针对 iPhone 5 屏幕(缺少 [email protected] 图像)进行优化,则此宏将不起作用,因为在这种情况下,屏幕尺寸仍将为 320x480。

我不认为这可能是一个问题,因为我不明白为什么我们要在未优化的应用程序中检测iPhone 5。

重要 - iOS 8 支持

在 iOS 8 上,类的属性现在反映设备方向
所以很明显,以前的代码不会开箱即用。
boundsUIScreen

为了解决此问题,您可以简单地使用 new 属性,而不是 ,因为它不会随方向而变化,并且它基于纵向模式。
请注意,尺寸以像素为单位,因此对于 iPhone 5,高度将为 1136 而不是 568。
nativeBoundsboundsnativeBounds

如果您还以 iOS 7 或更低版本为目标平台,请务必使用功能检测,因为在 iOS 8 之前进行调用会使您的应用崩溃:nativeBounds

if( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] )
{
    /* Detect using nativeBounds - iOS 8 and greater */
}
else
{
    /* Detect using bounds - iOS 7 and lower */
}

您可以按以下方式调整以前的宏:

#define IS_WIDESCREEN_IOS7 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
#define IS_WIDESCREEN_IOS8 ( fabs( ( double )[ [ UIScreen mainScreen ] nativeBounds ].size.height - ( double )1136 ) < DBL_EPSILON )
#define IS_WIDESCREEN      ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_WIDESCREEN_IOS8 : IS_WIDESCREEN_IOS7 )

显然,如果您需要检测iPhone 6或6 Plus,请使用相应的屏幕尺寸。

评论

7赞 Fabian Kreiser 9/16/2012
这是错误的,你必须使用#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
28赞 AliSoftware 9/17/2012
@H2CO3 :请注意,这里不需要比较,并且比较不会失败:只有当浮点值不能表示为精确数字(例如)时,才需要以这种方式使用差异进行比较。阅读此文章以获取更多信息;)DBL_EPSILON==1.0/3.0*3.0
2赞 OMGPOP 9/29/2012
这个答案是不正确的。为什么它得到了这么多人的赞?不能仅使用高度来确定它是否为宽屏。纨绔子弟。。。
5赞 david 10/8/2012
请允许我补充一点:如果你想让它与模拟器一起使用,请使用这个: #define IS_IPHONE ( ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @“iPhone” ] ) ||( [ [ [ [ UIDevice currentDevice ] 模型 ] isEqualToString: @“iPhone 模拟器” ] ) ) )
31赞 Ricardo Sanchez-Saez 10/17/2012
这个答案是疯狂的。这种关于建议不要将这些特定类型的浮点数(实际上是 - 如果你知道苹果应该知道总是 - 整数)与 == 进行比较的东西是无稽之谈,并且使事情过于复杂。此外,我认为最好使用 UI_USER_INTERFACE_IDIOM() 进行 iPhone 检测,因为它在设备和模拟器上都能正常工作(而且它可能比 UIDevice 方法更快)。这很好用,而且阅读起来更简单:#define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height==568)
15赞 CodeSmile 9/21/2012 #2

我冒昧地将 Macmade 的宏放入 C 函数中,并正确命名它,因为它检测宽屏可用性不一定是 iPhone 5。

如果项目不包含 [email protected],则宏也不会检测到在 iPhone 5 上运行。如果没有新的默认图像,iPhone 5 将报告常规的 480x320 屏幕尺寸(以磅为单位)。因此,检查不仅针对宽屏可用性,还针对启用的宽屏模式

BOOL isWidescreenEnabled()
{
    return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height - 
                                               (double)568) < DBL_EPSILON);
}

评论

0赞 Macmade 9/23/2012
出于性能原因,我仍然更喜欢宏。请看我的答案的编辑。它还检查模型。
1赞 Macmade 9/23/2012
你说iPhone 5将报告常规的480x320屏幕尺寸,而没有新的默认图像,这也是对的。但我认为在未优化的应用程序中检测 iPhone 5 是没有意义的。
0赞 Ivan Vučica 9/29/2012
@Macmade 确实,没有意义,但最好记住,以防检测不起作用。此外,函数可以是 d。它们还将被内联在编译器的优化器认为这是一个好主意的地方,以及它可以知道它是允许的(例如,函数在同一个模块中)。通过函数实现这样的东西有时可能会带来额外的类型检查。inline
4赞 CodeSmile 10/9/2012
与性能相关的问题是,为什么要在渲染循环期间运行此检查数千次?否则,性能就不是问题,清晰度和避免更重要的副作用。
0赞 Todd Lehman 5/15/2013
我为此给你打了 +1,因为我喜欢单独的函数而不是宏,但我必须指出它并不真正正确或完整。要检测宽屏,请不要看屏幕的高度。相反,查看纵横比,仅当纵横比大于或等于 16:9 时才返回 true。
69赞 Samrat Mazumdar 9/26/2012 #3

非常简单的解决方案

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}

评论

1赞 benjamin.ludwig 10/5/2012
哈哈·肖特和辛佩尔,做了同样:)砰将内容放入宏中并不是一个挑战......
2赞 hfossli 1/14/2013
好吧,不把东西放在宏或函数中很容易不干......从您需要多次进行此检查的那一刻起......
0赞 Resty 3/26/2014
是的,但是如上图所示定义宏,更方便易行,你不需要粘贴写这个,如果...每次。
0赞 Linh Nguyen 4/7/2014
谢谢,你救了我的命:D,但我不知道为什么 Macro:#define IS_IPHONE_5 (IS_IPHONE & [[UIScreen mainScreen] bounds].size.height == 568.0) ==> 在模拟器 iOS 7.1 中不起作用,在此之前我仍在使用 XCode 4.6。OMG iOS 7.1 和 Xcode 5
0赞 Sam B 10/20/2014
更新了下面的答案,以考虑 iPhone 6 和 6 以及屏幕尺寸
6赞 OMGPOP 9/29/2012 #4

这是我的 Cocos2D 项目的宏。对于其他应用程序应该相同。

#define WIDTH_IPAD 1024
#define WIDTH_IPHONE_5 568
#define WIDTH_IPHONE_4 480
#define HEIGHT_IPAD 768
#define HEIGHT_IPHONE 320

#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)

//width is height!
#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == WIDTH_IPHONE_5 )
#define IS_IPHONE_4 ( [ [ UIScreen mainScreen ] bounds ].size.height == WIDTH_IPHONE_4 )

#define cp_ph4(__X__, __Y__) ccp(cx_ph4(__X__), cy_ph4(__Y__))
#define cx_ph4(__X__) (IS_IPAD ? (__X__ * WIDTH_IPAD / WIDTH_IPHONE_4) : (IS_IPHONE_5 ? (__X__ * WIDTH_IPHONE_5 / WIDTH_IPHONE_4) : (__X__)))
#define cy_ph4(__Y__) (IS_IPAD ? (__Y__ * HEIGHT_IPAD / HEIGHT_IPHONE) : (__Y__))

#define cp_pad(__X__, __Y__) ccp(cx_pad(__X__), cy_pad(__Y__))
#define cx_pad(__X__) (IS_IPAD ? (__X__) : (IS_IPHONE_5 ? (__X__ * WIDTH_IPHONE_5 / WIDTH_IPAD) : (__X__ * WIDTH_IPHONE_4 / WIDTH_IPAD)))
#define cy_pad(__Y__) (IS_IPAD ? (__Y__) : (__Y__ * HEIGHT_IPHONE / HEIGHT_IPAD))
0赞 user1025285 10/10/2012 #5

使用以下代码:

CGFloat screenScale = [[UIScreen mainScreen] scale];

CGRect screenBounds = [[UIScreen mainScreen] bounds]; 

CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale); 

if (screenSize.height==1136.000000)
{ 
    // Here iPhone 5 View

    // Eg: Nextview~iPhone5.Xib
} else {
   // Previous Phones 

   // Eg : Nextview.xib
}
2赞 Jeff Hay 10/11/2012 #6

借用 Samrat Mazumdar 的回答,这里有一个估计设备屏幕尺寸的简短方法。它适用于最新的设备,但在将来的设备上可能会失败(因为所有猜测方法都可能)。如果设备正在镜像,它也会感到困惑(返回设备的屏幕大小,而不是镜像的屏幕大小)

#define SCREEN_SIZE_IPHONE_CLASSIC 3.5
#define SCREEN_SIZE_IPHONE_TALL 4.0
#define SCREEN_SIZE_IPAD_CLASSIC 9.7

+ (CGFloat)screenPhysicalSize
{
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        if (result.height < 500)
            return SCREEN_SIZE_IPHONE_CLASSIC;  // iPhone 4S / 4th Gen iPod Touch or earlier
        else
            return SCREEN_SIZE_IPHONE_TALL;  // iPhone 5
    }
    else
    {
        return SCREEN_SIZE_IPAD_CLASSIC; // iPad
    }
} 

评论

0赞 Daniel 12/11/2012
需要对iPad mini进行修改,我不相信你能够在这个庄园中确定。
0赞 Jeff Hay 12/22/2012
是的,iPad mini 的分辨率与 iPad2 相同,因此此方法不适用于此。不知道现在如何处理这个案子......
1赞 Daniel 12/22/2012
你不应该这样做。您可以检查“iPad 2,5”的设备标识符,还需要检查 2,6 和 2,7 - 仅限 wifi 版本、gsm 和 CDMA。但这意味着下一代iPad mini将发布,您也需要更新为那些您事先无法知道的标识符的硬编码。你无法完全知道你什么时候在iPad mini上,因为你真的不应该尝试针对较小的屏幕进行“优化”
232赞 hfossli 10/31/2012 #7

针对 SDK 和操作系统的任意组合进行测试和设计:

迅速

添加了 iPad 类型。 iPad 2 和 iPad mini 是非视网膜 iPad。iPad Mini 2 及更高版本、iPad 3、4、iPad Air、Air 2、Air 3 和 iPad Pro 9.7 的逻辑分辨率相同,均为 1024。iPad Pro 的最大长度为 1366。 参考

import UIKit

public enum DisplayType {
    case unknown
    case iphone4
    case iphone5
    case iphone6
    case iphone6plus
    case iPadNonRetina
    case iPad
    case iPadProBig
    static let iphone7 = iphone6
    static let iphone7plus = iphone6plus
}

public final class Display {
    class var width:CGFloat { return UIScreen.main.bounds.size.width }
    class var height:CGFloat { return UIScreen.main.bounds.size.height }
    class var maxLength:CGFloat { return max(width, height) }
    class var minLength:CGFloat { return min(width, height) }
    class var zoomed:Bool { return UIScreen.main.nativeScale >= UIScreen.main.scale }
    class var retina:Bool { return UIScreen.main.scale >= 2.0 }
    class var phone:Bool { return UIDevice.current.userInterfaceIdiom == .phone }
    class var pad:Bool { return UIDevice.current.userInterfaceIdiom == .pad }
    class var carplay:Bool { return UIDevice.current.userInterfaceIdiom == .carPlay }
    class var tv:Bool { return UIDevice.current.userInterfaceIdiom == .tv }
    class var typeIsLike:DisplayType {
        if phone && maxLength < 568 {
            return .iphone4
        }
        else if phone && maxLength == 568 {
                return .iphone5
        }
        else if phone && maxLength == 667 {
            return .iphone6
        }
        else if phone && maxLength == 736 {
            return .iphone6plus
        }
        else if pad && !retina {
            return .iPadNonRetina
        }
        else if pad && retina && maxLength == 1024 {
            return .iPad
        }
        else if pad && maxLength == 1366 {
            return .iPadProBig
        }
        return .unknown
    }
}

查看实际操作 https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

注意:例如,如果 iPhone 6 处于缩放模式,则 UI 是 iPhone 5 的放大版本。这些功能不是确定设备类型,而是显示模式,因此iPhone 5是本例中所需的结果。

Objective-C语言

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_RETINA ([[UIScreen mainScreen] scale] >= 2.0)

#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
#define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT))
#define SCREEN_MIN_LENGTH (MIN(SCREEN_WIDTH, SCREEN_HEIGHT))
#define IS_ZOOMED (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

#define IS_IPHONE_4_OR_LESS (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
#define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
#define IS_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

用法:http://pastie.org/9687735

注意:例如,如果 iPhone 6 处于缩放模式,则 UI 是 iPhone 5 的放大版本。这些功能不是确定设备类型,而是显示模式,因此iPhone 5是本例中所需的结果。

评论

1赞 hfossli 11/4/2012
iPhone 5 将报告常规的 480x320 屏幕尺寸,没有新的默认图像。对我来说,这是通缉的行为。
3赞 bshirley 5/2/2013
一个可能有用的补充是,这将有助于确定 iPhone4 和 iPhone5 以及 iPad 视网膜和非视网膜之间的区别#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)
1赞 hfossli 9/9/2014
我不同意。我认为应该省略“宽屏”术语,因为它很快就会过时。
1赞 hfossli 11/5/2014
@Dvole这就是 iOS 8 的行为方式。用于在 iPhone 5 上获得 568 的所有旋转。SCREEN_MAX_LENGTH
1赞 hfossli 11/17/2014
@MattParkins我建议使用更强大的模型检查 stackoverflow.com/questions/13366976/...
1赞 Nithin M Keloth 12/11/2012 #8
CGFloat height = [UIScreen mainScreen].bounds.size.height;

NSLog(@"screen soze is %f",height);

  if (height>550) {

          // 4" screen-do some thing
     }

  else if (height<500) {

        // 3.5 " screen- do some thing

     }
2赞 Bhavesh Dhaduk 2/8/2013 #9

我认为如果这个宏可以在设备和模拟器中工作,那应该很好,下面是解决方案。

#define IS_WIDESCREEN (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)568) < DBL_EPSILON)
#define IS_IPHONE (([[[UIDevice currentDevice] model] isEqualToString:@"iPhone"]) || ([[[UIDevice currentDevice] model] isEqualToString: @"iPhone Simulator"]))
#define IS_IPOD   ([[[UIDevice currentDevice]model] isEqualToString:@"iPod touch"])
#define IS_IPHONE_5 ((IS_IPHONE || IS_IPOD) && IS_WIDESCREEN)
1赞 3d0 3/1/2013 #10

在很多层面上,依赖大小是错误的。我们向系统询问怎么样?

- (NSString *) getDeviceModel
{
    struct utsname systemInfo;
    uname(&systemInfo);
    return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}

摘自检测硬件类型的最佳方法,iPhone4 或 iPhone5?,edzio27 答案。

5赞 D-eptdeveloper 9/12/2013 #11
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
    // This is iPhone 5 screen
} else {
    // This is iPhone 4 screen
}
2赞 valvoline 11/8/2013 #12

我发现答案不包括模拟器的特例。

#define IS_WIDESCREEN ( [ [ UIScreen mainScreen ] bounds ].size.height == 568  )
#define IS_IPHONE ([[ [ UIDevice currentDevice ] model ] rangeOfString:@"iPhone"].location != NSNotFound)
#define IS_IPAD ([[ [ UIDevice currentDevice ] model ] rangeOfString:@"iPad"].location != NSNotFound)
#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )
1赞 Zeeshan 4/10/2014 #13

这样,您可以检测设备系列。

    #import <sys/utsname.h>
    NSString* deviceName()
    {
        struct utsname systemInformation;
        uname(&systemInformation);
        NSString *result = [NSString stringWithCString:systemInformation.machine
                                              encoding:NSUTF8StringEncoding];
        return result;
    }

    #define isIPhone5  [deviceName() rangeOfString:@"iPhone5,"].location != NSNotFound
    #define isIPhone5S [deviceName() rangeOfString:@"iPhone6,"].location != NSNotFound
2赞 Mubin Shaikh 5/19/2014 #14
+(BOOL)isDeviceiPhone5
{
    BOOL iPhone5 = FALSE;

    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    if (screenBounds.size.height == 568)
    {
        // code for 4-inch screen
        iPhone5 = TRUE;
    }
    else
    {
        iPhone5 = FALSE;
        // code for 3.5-inch screen
    }
    return iPhone5;

}

评论

0赞 mcont 6/26/2014
iPhone5 = FALSE;是不必要的,因为如果不更改变量,则该变量已经具有该值
28赞 Sam B 9/24/2014 #15

我们现在需要考虑iPhone 6和6Plus的屏幕尺寸。这是一个更新的答案

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    //its iPhone. Find out which one?

    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    else if(result.height == 568)
    {
        // iPhone 5
    }
    else if(result.height == 667)
    {
        // iPhone 6
    }
   else if(result.height == 736)
    {
        // iPhone 6 Plus
    }
}
else
{
     //its iPad
}

一些有用的信息

iPhone 6 Plus   736x414 points  2208x1242 pixels    3x scale    1920x1080 physical pixels   401 physical ppi    5.5"
iPhone 6        667x375 points  1334x750 pixels     2x scale    1334x750 physical pixels    326 physical ppi    4.7"
iPhone 5        568x320 points  1136x640 pixels     2x scale    1136x640 physical pixels    326 physical ppi    4.0"
iPhone 4        480x320 points  960x640 pixels      2x scale    960x640 physical pixels     326 physical ppi    3.5"
iPhone 3GS      480x320 points  480x320 pixels      1x scale    480x320 physical pixels     163 physical ppi    3.5"

评论

0赞 Coldsteel48 1/4/2015
它只是对我不起作用 iPhone 5 决定为 4 iPhone 6+ 根本没有决定哦,我明白了,我在横向,我应该随宽度改变高度:)
0赞 Sam B 1/4/2015
如果您的应用处于横向模式,请确保将 result.height 更改为 result.width
0赞 Coldsteel48 1/5/2015
嗯。。在 iPhone 4 (iOS 6.0) 上,它没有交换:(可能是iOS 6.0 prob或iPhone 4 ?
0赞 Coldsteel48 1/5/2015
好的,我检查了仅在 iOS 8 及更高版本中交换的视图
0赞 MD SHAHIDUL ISLAM 5/13/2015
iPhone 6 给出高度 = 568
-2赞 Vaibhav Sharma 9/24/2014 #16

用于检测所有版本的iPhone和iPad设备。

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0) 

评论

0赞 vikingosegundo 9/29/2014
iPhone 6没有视网膜显示屏?
0赞 Vaibhav Sharma 10/1/2014
iPhone6 具有 ratina(@2X) 显示屏。iPhone6 plus具有HD(@3X)显示屏。
0赞 vikingosegundo 10/1/2014
那么,如果在 iPhone 6 plus 上进行测试,会执行 1x 代码吗?IS_RETINA
0赞 Vaibhav Sharma 10/6/2014
请参阅此链接。stackoverflow.com/questions/25756589/......
1赞 vikingosegundo 10/6/2014
你不明白:你的规则会让步,它应该让步的地方.无论如何:因为您只是复制和粘贴:-1@1x@3x
1赞 Aritra Das 9/29/2014 #17

如果项目是使用 Xcode 6 创建的,请使用下面提到的代码来检测设备。

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] nativeBounds].size.width,(int)[[UIScreen mainScreen] nativeBounds].size.height);

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
        if([[UIScreen mainScreen] nativeBounds].size.height == 960 || [[UIScreen mainScreen] nativeBounds].size.height == 480){
            printf("Device Type : iPhone 4,4s ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1136){
            printf("Device Type : iPhone 5,5S/iPod 5 ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1334){
            printf("Device Type : iPhone 6 ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 2208){
            printf("Device Type : iPhone 6+ ");

        }
    }
}else{
    printf("Device Type : iPad");
}

如果项目是在 Xcode 5 中创建并在 Xcode 6 中打开的,请使用下面提到的代码来检测设备。(如果没有为 iPhone 6,6+ 分配启动图像,则此代码有效)

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] nativeBounds].size.width,(int)[[UIScreen mainScreen] nativeBounds].size.height);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
       if([[UIScreen mainScreen] nativeBounds].size.height == 960 || [[UIScreen mainScreen] nativeBounds].size.height == 480){
            printf("Device Type : iPhone 4,4s");
            appType=1;
        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1136 || [[UIScreen mainScreen] nativeBounds].size.height == 1704){
            printf("Device Type : iPhone 5,5S,6,6S/iPod 5 ");
            appType=3;
        }
    }
}else{
    printf("Device Type : iPad");
    appType=2;
}

如果您仍在使用 Xcode 5,请使用以下代码来检测设备(不会检测到 iPhone 6 和 6+)

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] bounds].size.width,(int)[[UIScreen mainScreen] bounds].size.height);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        CGFloat scale = [UIScreen mainScreen].scale;
        result = CGSizeMake(result.width * scale, result.height * scale);
        if(result.height == 960 || result.height == 480){
            printf("Device Type : iPhone 4,4S ");

        }else if(result.height == 1136){
            printf("Device Type : iPhone 5s/iPod 5");

        }
    }
}else{
    printf("Device Type : iPad");

}
11赞 Ginger 10/7/2014 #18

这是我们的代码,在ios7 / ios8上通过的测试适用于iphone4,iphone5,ipad,iphone6,iphone6p,无论是在设备还是模拟器上:

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) // iPhone and       iPod touch style UI

#define IS_IPHONE_5_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0f)
#define IS_IPHONE_6_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0f)
#define IS_IPHONE_6P_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0f)
#define IS_IPHONE_4_AND_OLDER_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height < 568.0f)

#define IS_IPHONE_5_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 568.0f)
#define IS_IPHONE_6_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 667.0f)
#define IS_IPHONE_6P_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 736.0f)
#define IS_IPHONE_4_AND_OLDER_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) < 568.0f)

#define IS_IPHONE_5 ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_5_IOS8 : IS_IPHONE_5_IOS7 )
#define IS_IPHONE_6 ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_6_IOS8 : IS_IPHONE_6_IOS7 )
#define IS_IPHONE_6P ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_6P_IOS8 : IS_IPHONE_6P_IOS7 )
#define IS_IPHONE_4_AND_OLDER ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_4_AND_OLDER_IOS8 : IS_IPHONE_4_AND_OLDER_IOS7 )

评论

0赞 whyoz 6/10/2015
我正在iPhone 6P上进行测试,而我的if语句处于IS_IPHONE_5状态?这怎么可能,你的代码看起来不错?我用一个简单的if/else直接复制和粘贴,我知道我的手机是运行iOS 6的8.3。
7赞 Borbea 1/6/2015 #19

我使用了 hfossli 的答案并将其翻译成 Swift

let IS_IPAD = UIDevice.currentDevice().userInterfaceIdiom == .Pad
let IS_IPHONE = UIDevice.currentDevice().userInterfaceIdiom == .Phone
let IS_RETINA = UIScreen.mainScreen().scale >= 2.0

let SCREEN_WIDTH = UIScreen.mainScreen().bounds.size.width
let SCREEN_HEIGHT = UIScreen.mainScreen().bounds.size.height
let SCREEN_MAX_LENGTH = max(SCREEN_WIDTH, SCREEN_HEIGHT)
let SCREEN_MIN_LENGTH = min(SCREEN_WIDTH, SCREEN_HEIGHT)

let IS_IPHONE_4_OR_LESS = (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
let IS_IPHONE_5 = (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
let IS_IPHONE_6 = (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
let IS_IPHONE_6P = (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)
1赞 William Hu 10/27/2015 #20
  1. 添加“新的 Swift 文件”->AppDelegateEx.swift

  2. 将扩展添加到AppDelegate

    import UIKit
    extension AppDelegate {
         class func isIPhone5 () -> Bool{
             return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 568.0
        }
        class func isIPhone6 () -> Bool {
            return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 667.0
        }
        class func isIPhone6Plus () -> Bool {
            return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 736.0
        }  
    }
    
  3. 用法:

        if AppDelegate.isIPhone5() {
            collectionViewTopConstraint.constant = 2
        }else if AppDelegate.isIPhone6() {
            collectionViewTopConstraint.constant = 20
        }
    
0赞 Pawel Molodkin 4/13/2016 #21

这是对设备的正确测试,不依赖于方向

- (BOOL)isIPhone5
{
    CGSize size = [[UIScreen mainScreen] bounds].size;
    if (MIN(size.width,size.height) == 320 && MAX(size.width,size.height == 568)) {
        return YES;
    }
    return NO;
}
3赞 zubko 5/22/2016 #22

在 Swift 中,我喜欢在 iOS 8+ 项目上做一个扩展,比如:UIScreen

extension UIScreen {

    var isPhone4: Bool {
        return self.nativeBounds.size.height == 960;
    }

    var isPhone5: Bool {
        return self.nativeBounds.size.height == 1136;
    }

    var isPhone6: Bool {
        return self.nativeBounds.size.height == 1334;
    }

    var isPhone6Plus: Bool {
        return self.nativeBounds.size.height == 2208;
    }

}

(注意:以像素为单位)。nativeBounds

然后代码将如下所示:

if UIScreen.mainScreen().isPhone4 {
    // do smth on the smallest screen
}

因此,代码清楚地表明,这是对主屏幕的检查,而不是对设备型号的检查。

2赞 William T. 11/3/2016 #23

这个问题已经回答了一百次,但这个解决方案对我来说效果最好,并且帮助解决了引入新设备并且我没有定义大小时的问题。

Swift 5 助手:

extension UIScreen {
    func phoneSizeInInches() -> CGFloat {
        switch (self.nativeBounds.size.height) {
        case 960, 480:
            return 3.5  //iPhone 4
        case 1136:
            return 4    //iPhone 5
        case 1334:
            return 4.7  //iPhone 6
        case 2208:
            return 5.5  //iPhone 6 Plus
        case 2436:
            return 5.8  //iPhone X
        case 1792:
            return 6.1  //iPhone XR
        case 2688:
            return 6.5  //iPhone XS Max
        default:
            let scale = self.scale
            let ppi = scale * 163
            let width = self.bounds.size.width * scale
            let height = self.bounds.size.height * scale
            let horizontal = width / ppi, vertical = height / ppi
            let diagonal = sqrt(pow(horizontal, 2) + pow(vertical, 2))
            return diagonal
        }
    }
}

这是因为很容易记住手机的英寸尺寸,例如“5.5 英寸”或“4.7 英寸”设备,但很难记住确切的像素尺寸。

if UIScreen.main.phoneSizeInInches() == 4 {
  //do something with only 4 inch iPhones
}

这也使你有机会做这样的事情:

if UIScreen.main.phoneSizeInInches() < 5.5 {
  //do something on all iPhones smaller than the plus
}

默认值:尝试使用屏幕大小和比例来尝试计算对角线英寸。这是为了以防出现一些新的设备尺寸,它将尽力确定,并且代码(例如最后一个示例)仍然应该有效。

1赞 Julian D. 4/9/2017 #24

在 Swift 3 中,你可以使用我的简单类 KRDeviceType。

https://github.com/ulian-onua/KRDeviceType

它有据可查,支持运算符 ==、>=、<=。

例如,要检测设备是否具有iPhone 6 / 6s / 7的边界,您可以使用下一个比较:

if KRDeviceType() == .iPhone6 {
// Perform appropiate operations
}

要检测设备是否具有iPhone 5 / 5S / SE或更早版本(iPhone 4s)的边界,您可以使用下一个比较:

if KRDeviceType() <= .iPhone5 {   //iPhone 5/5s/SE of iPhone 4s
// Perform appropiate operations (for example, set up constraints for those old devices)
}