我刚刚升级到Xcode 4.5 GM,发现你现在可以将“4英寸视网膜”大小应用到故事板中的视图控制器上。

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

我该怎么做呢?


当前回答

Add a 'New Swift File'-> AppDelegateEx.swift add an extension to 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 } } usage: if AppDelegate.isIPhone5() { collectionViewTopConstraint.constant = 2 }else if AppDelegate.isIPhone6() { collectionViewTopConstraint.constant = 20 }

其他回答

非常简单的解决方法

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

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

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
}

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

首先,您不应该重新构建所有视图以适应新屏幕,也不应该针对不同的屏幕大小使用不同的视图。

使用iOS的自动调整大小功能,这样你的视图就可以调整,并适应任何屏幕大小。

这并不难,阅读一些相关的文档。这会节省你很多时间。

iOS 6也提供了相关的新功能。 请务必阅读苹果开发者网站上的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 )

在比较浮点数时,使用带有epsilon的晶圆厂是为了防止精度错误,正如H2CO3在评论中指出的那样。

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

if( IS_IPHONE_5 )
{}
else
{}

编辑-更好的检测

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

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

让我们重命名原始宏is_宽屏:

#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屏幕进行优化(缺少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,使用相应的屏幕尺寸。

Add a 'New Swift File'-> AppDelegateEx.swift add an extension to 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 } } usage: if AppDelegate.isIPhone5() { collectionViewTopConstraint.constant = 2 }else if AppDelegate.isIPhone6() { collectionViewTopConstraint.constant = 20 }

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