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

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

我该怎么做呢?


当前回答

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

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

它有很好的文档,并支持运算符==,>=,<=。

例如,要检测设备是否有iPhone 6/6s/7的边界,你可以使用next比较:

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

其他回答

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

通过这种方式,您可以检测设备系列。

    #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

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

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

它有很好的文档,并支持运算符==,>=,<=。

例如,要检测设备是否有iPhone 6/6s/7的边界,你可以使用next比较:

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

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 }

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

使用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,使用相应的屏幕尺寸。