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


300

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

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

我该怎么办?


2
您不必每次都构建两次“窗口”。只有那些应该与屏幕尺寸完全匹配的显示器才需要重新发送。解决方案似乎很明显,只需检查窗口尺寸并根据返回的大小添加大小写决定。
直到2012年

1
好吧,基本上是这样,但是我想以完全不同的方式使用额外的屏幕尺寸,就像使用横向屏幕一样。
Finn Gaida 2012年


是否应该根据新设备更新此问题?例如“如何通过屏幕尺寸检测iOS设备”?
hfossli 2014年

Answers:


467

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

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

那不是很难,请阅读一些文档有关此。这样可以节省您很多时间。

iOS 6还提供了与此相关的新功能。
确保阅读Apple Developer网站上的iOS 6 API更改日志
并检查新的iOS 6 AutoLayout功能。

也就是说,如果您确实需要检测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 )

fabs正如H2CO3的注释所指出的,在此处使用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机型宽屏屏幕,并且可以重新定义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上,该类的bounds属性UIScreen现在反映设备的方向
因此很明显,先前的代码无法立即使用。

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

如果您还定位到iOS 7或更低版​​本,请确保使用功能检测,因为nativeBounds在iOS 8之前致电会导致您的应用崩溃:

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
这是错误的,您必须使用#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
Fabian Kreiser

28
@ H2CO3:请注意,DBL_EPSILON此处不必进行比较,并且==比较不会失败:仅当无法将浮点值表示为精确数字时(1.0/3.0*3.0例如),才需要使用差异进行比较。阅读本文以获取更多信息;)
AliSoftware 2012年

2
这个答案是不正确的。为什么会引起这么多赞许?您不能仅使用高度来确定它是否为宽屏。伙计...
OMGPOP 2012年

5
我可以补充一下:如果要与模拟器一起使用,请使用以下命令:#define IS_IPHONE(([[[[UIDevice currentDevice]模型] isEqualToString:@“ iPhone”])||([[[[UIDevice currentDevice]模型] isEqualToString: @“ iPhone模拟器”])))
大卫2012年

31
这个答案是疯狂的。建议不要将这些特殊类型的浮点数(实际上是-并且,如果您知道Apple应该知道-将始终是-整数)与==进行比较,这是无稽之谈,会使事情复杂化。另外,我认为最好使用UI_USER_INTERFACE_IDIOM()进行iPhone检测,因为它在设备和模拟器上都可以正常工作(并且可能比UIDevice方法更快)。这可以很好地工作,并且更易于阅读:#define IS_IPHONE5(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone && [UIScreen mainScreen] .bounds.size.height == 568)
里卡多·桑切斯·塞兹

232

已针对SDK和OS的任何组合进行测试和设计:

迅速

添加了iPad类型。iPad 2和iPad mini是非视网膜iPad。虽然ipad公司赠送2以上,iPad的3,4,iPad的空气,空气2,空气3,和ipad临9.7有1024的iPad临的相同逻辑分辨率具有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是理想的结果。

物镜

#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
iPhone 5将报告常规的480x320屏幕尺寸,没有新的默认图片。对我来说这是通缉的行为。
hfossli 2012年

3
可能有用的补充#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)将有助于确定iPhone4和iPhone5与iPad视网膜和非视网膜之间的区别
bshirley

1
我不同意。我认为,“宽屏”术语应予以淘汰,因为它已经过时了。
hfossli 2014年

1
@Dvole就是iOS 8的行为方式。使用SCREEN_MAX_LENGTH获得的所有旋转568对iPhone 5
hfossli

1
@MattParkins我建议使用更强大的模型检查stackoverflow.com/questions/13366976/…
hfossli 2014年

69

真正简单的解决方案

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
哈哈short和simpel,做了同样的事情:)为保持低开销而努力!将内容放入宏并不是挑战……
benjamin.ludwig 2012年

2
好吧,不要将事情放到宏或函数中
就很

是的,但是如上所示定义宏更方便,更简单,如果每次……都无需粘贴。
Resty 2014年

谢谢,您救了我的命:D,但是我不知道为什么宏:#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
Linh Nguyen

以下更新的答案适用于iPhone 6和6以及屏幕尺寸
Sam B

28

现在,我们需要考虑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+根本没有决定哦,我明白了,我在风景中,我应该用宽度更改高度:)
ColdSteel

如果您的应用程序处于横向模式,请确保将result.height更改为result.width
Sam B

嗯..在iPhone 4(iOS 6.0)上没有交换:(可能是iOS 6.0的问题或iPhone 4?
ColdSteel15年

好吧,我检查了仅在iOS 8和更高版本中交换的视图
ColdSteel

iPhone 6高度= 568
MaxEcho

15

我已经自由地将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);
}

由于性能原因,我仍然更喜欢宏。请查看我的答案的修改。它还会检查模型。
Macmade 2012年

1
您也说对了,iPhone 5将报告常规的480x320屏幕尺寸,而没有新的默认图片。但是我认为在未优化的应用程序中检测iPhone 5没有意义。:)
Macmade

@Macmade的确没有意义,但是最好记住以防检测无效。此外,可以设置功能inline。在编译器的优化器认为这是一个好主意的地方以及可以知道其允许的地方(例如,函数在同一模块中),它们也会被内联。通过函数实现类似的东西有时可能会带来额外的类型检查。
伊万·武西卡(IvanVučica)2012年

4
与性能相关的问题是,为什么要在渲染循环中运行此检查数千次?否则,性能不是问题,也不是明确的,并且避免了更重要的副作用。
LearnCocos2D 2012年

我为此给了+1,因为我喜欢单独的功能而不是宏,但是我必须指出,它并不是真正正确或完整的。要检测宽屏,请不要看屏幕的高度。而是查看长宽比,仅在长宽比大于或等于16:9时才返回true。
Todd Lehman

11

这是我们的代码,无论是在设备还是模拟器上,都在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以上版本。
whyoz 2015年

7

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

6

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

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

3

在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

借鉴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的修订,我相信您无法在此庄园中确定。
丹尼尔(Daniel)

是的,iPad mini具有与iPad2相同的分辨率,因此该方法不起作用。不确定现在如何处理该案件...
Jeff Hay

1
你不应该这样 您可以检查“ iPad 2,5”的设备标识符,也需要检查2,6和2,7-仅限wifi版本,gsm和CDMA。但这意味着将发布下一个iPad mini,您还需要将硬编码更新为您之前不知道的标识符。您无法完全确定何时使用iPad mini,因为实际上您不应该尝试为较小的屏幕“优化”
Daniel

2

我认为如果此宏可以在设备和模拟器中使用应该很好,以下是解决方案。

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

2

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

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

2
+(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;是不必要的,因为如果不更改该变量,则该变量已经具有该值
mcont 2014年

1
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

     }


1

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

    #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

1

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

}

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

1

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

1

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

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 5.5  //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 all iPhones smaller than the plus
}

默认:尝试使用屏幕大小和规模,试图计算英寸对角线。如果出现某些新设备大小的情况,它将尽力确定并进行编码(例如最后一个示例)仍然可以使用。


0

使用以下代码:

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
}

0

这是对设备的正确测试,而不取决于方向

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

-2

用于检测所有版本的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没有视网膜显示屏吗?
vikingosegundo

iPhone6的显示屏为ratina(@ 2X)。iPhone6 plus具有HD(@ 3X)显示屏。
Vaibhav Sharma 2014年

那么,如果IS_RETINA在iPhone 6 plus上进行了测试,则执行1x代码?
vikingosegundo 2014年


1
您没有得到:您的规则会@1x在应该产生的地方屈服@3x。无论如何:就像您只是复制粘贴:-1
vikingosegundo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.