ChatGPT解决这个技术问题 Extra ChatGPT

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

我刚刚升级到 Xcode 4.5 GM,发现您现在可以将 '4" Retina' 尺寸应用到情节提要中的视图控制器。

现在,如果我想创建一个在 iPhone 4 和 5 上运行的应用程序,当然我必须构建每个窗口两次,但我还必须检测用户是否拥有 3.5" 或 4" 屏幕的 iPhone,然后应用看法。

我该怎么做?

您不必构建每个“窗口”两次。只有那些应该与屏幕尺寸完全匹配的才需要重新布局。解决方案似乎相当明显,只需检查窗口尺寸并根据返回的大小添加案例决策。
嗯,基本上这是真的,但我想以完全不同的方式使用额外的屏幕尺寸,就像你可以使用横向屏幕一样。
这个问题是否应该根据新设备进行更新?例如“如何通过屏幕尺寸检测 iOS 设备”?

C
Cœur

首先,您不应该重建所有视图以适应新屏幕,也不应该为不同的屏幕尺寸使用不同的视图。

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

这不是很难,请阅读some documentation。它将为您节省大量时间。

iOS 6 还为此提供了新功能。
请务必阅读 Apple 开发者网站上的 iOS 6 API changelog
并查看新的 iOS 6 AutoLayout 功能。

也就是说,如果您真的需要检测 iPhone 5,您可以简单地依赖 screen size

[ [ UIScreen mainScreen ] bounds ].size.height

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

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

正如 H2CO3 在评论中指出的那样,在比较浮点时,将 fabs 与 epsilon 一起使用是为了防止精度错误。

因此,从现在开始,您可以在标准 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 型号 AND 宽屏,并且我们可以重新定义 IS_IPHONE_5 宏:

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

另请注意,正如@LearnCocos2D 所述,如果应用程序未针对 iPhone 5 屏幕进行优化(缺少 Default-568h@2x.png 图像),则此宏将不起作用,因为在这种情况下屏幕尺寸仍为 320x480一件事。

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

重要 - iOS 8 支持

在 iOS 8 上,UIScreen 类的 bounds 属性现在反映了设备方向
很明显,前面的代码不能开箱即用。

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

如果您还针对 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,请使用相应的屏幕尺寸。


这是错误的,您必须使用 #define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
@H2CO3:请注意,这里不需要与 DBL_EPSILON 进行比较,并且 == 比较将不会失败:只有在浮点值的情况下才需要以这种方式使用差异进行比较不能表示为精确的数字(例如 1.0/3.0*3.0)。阅读 this article 了解更多信息;)
这个答案是不正确的。为什么它得到了这么多的赞?您不能仅使用高度来确定它是否是宽屏。伙计...
我可以补充一下:如果您希望它与模拟器一起使用:#define IS_IPHONE ( ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPhone" ] ) || ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @“iPhone 模拟器”]))
这个答案很疯狂。关于建议不要将这些特定类型的浮点数(实际上是——如果你知道苹果应该知道它总是——整数)与 == 进行比较的东西是无稽之谈,而且会使事情变得过于复杂。另外,我认为最好使用 UI_USER_INTERFACE_IDIOM() 进行 iPhone 检测,因为它在设备和模拟器上都可以正常工作(而且它可能比 UIDevice 方法更快)。这很好用并且更容易阅读:#define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height==568)
f
felixwcf

针对 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 的 maxLength 为 1366。 Reference

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 是本示例中所需的结果。


iPhone 5 将报告常规的 480x320 屏幕尺寸,没有新的默认图像。对我来说,这是通缉行为。
一个可能有用的补充是 #define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0) 这将有助于确定 iPhone4 和 iPhone5 以及 iPad 视网膜和非视网膜之间的区别
我不同意。我认为应该忽略“宽屏”术语,因为它很快就过时了。
@Dvole 这就是 iOS 8 的行为方式。在 iPhone 5 上使用 SCREEN_MAX_LENGTH 在所有旋转中获得 568。
@MattParkins 我建议使用更强大的模型检查stackoverflow.com/questions/13366976/…
S
Samrat Mazumdar

非常简单的解决方案

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

哈哈,简短而简单,做了同样的事情:) 为保持低开销而振作起来!将东西放入宏中并不是一个挑战......
好吧,不把东西放在宏或函数中很容易不干燥......从你需要不止一次做这个检查的那一刻起......
是的,但是如上所示定义宏,更方便和容易,你不需要每次都粘贴写这个。
谢谢,你救了我的命: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
更新了下面的答案以考虑 iPhone 6 和 6 以及屏幕尺寸
S
Sam B

我们现在需要考虑 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"

它只是对我不起作用 iPhone 5 决定为 4 iPhone 6+ 根本没有决定哦我明白了我在横向我应该用宽度改变高度:)
如果您的应用程序处于横向模式,请确保将 result.height 更改为 result.width
嗯..在iPhone 4(iOS 6.0)上它没有交换:(可能是iOS 6.0 prob或iPhone 4?
好的,我检查了仅在 iOS 8 及更高版本中交换的视图
iPhone 6 给出高度 = 568
L
LearnCocos2D

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

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

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

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

这是我们的代码,在 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 )

我在 iPhone 6P 上进行测试,我的 if 语句落入 IS_IPHONE_5 条件?这怎么可能,你的代码看起来不错?我用一个简单的 if/else 直接复制和粘贴,我知道我的手机是运行 iOS 8.3 的 6 plus。
B
Borbea

我使用了 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)

O
OMGPOP

这是我的 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))

D
D-eptdeveloper
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
    // This is iPhone 5 screen
} else {
    // This is iPhone 4 screen
}

z
zubko

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

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


J
Jeff Hay

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

iPad mini 需要改版,我不相信你能在这个庄园里确定。
是的,iPad mini 的分辨率和 iPad2 一样,所以这个方法不适用。现在不知道如何处理这种情况......
你不应该。您可以检查“iPad 2,5”的设备标识符,还需要检查 2,6 和 2,7 - 仅限 wifi 版本、gsm 和 CDMA。但这意味着下一个 iPad mini 将发布,您也需要将这些标识符更新为硬编码,而这些标识符是您事先无法知道的。您无法完全知道您何时使用 iPad mini,因为实际上您不应该尝试针对较小的屏幕进行“优化”
B
Bhavesh Dhaduk

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

#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)

v
valvoline

我发现答案不包括模拟器的特殊情况。

#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 )

M
Mubin Shaikh
+(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;

}

iPhone5 = FALSE; 是不必要的,因为如果没有更改,变量已经具有该值
A
Alexandre G

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

斯威夫特 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
}

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


N
Nithin M Keloth
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

     }

C
Community

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

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

取自 Best way to detect hardware type, iPhone4 or iPhone5?,edzio27 答案。


Z
Zeeshan

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

    #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

A
Aritra Das

如果项目是使用 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");

}

W
William Hu

添加一个 'New Swift File'-> AppDelegateEx.swift 为 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 } } 用法:如果 AppDelegate.isIPhone5() { collectionViewTopConstraint.constant = 2 }else if AppDelegate. isIPhone6() { collectionViewTopConstraint.constant = 20 }


J
Julian D.

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

L
Laszlo

使用以下代码:

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
}

P
Pawel Molodkin

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

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

h
hfossli

用于检测所有版本的 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) 

iPhone 6 没有视网膜显示屏?
iPhone6 有ratina(@2X) 显示屏。 iPhone6 plus 有高清(@3X) 显示屏。
那么,如果在 iPhone 6 plus 上测试 IS_RETINA,会执行 1x 代码吗?
你不明白:你的规则将产生 @1x,它应该产生 @3x。无论如何:因为您只是复制和粘贴:-1