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

本文翻译自:How to detect iPhone 5 (widescreen devices)?

I've just upgraded to XCode 4.5 GM and found out that you can now apply the '4" Retina' size to your view controller in the storyboard. 我刚刚升级到XCode 4.5 GM,发现你现在可以将“4”Retina'大小应用到故事板中的视图控制器。

Now if I want to create an application that runs on both iPhone 4 and 5, of course I have to build every window twice, but I also have to detect whether the user has an iPhone with 3.5" or 4" screen and then apply the view. 现在,如果我想创建一个在iPhone 4和5上运行的应用程序,当然我必须构建每个窗口两次,但我还必须检测用户是否有一个3.5“或4”屏幕的iPhone,然后应用视图。

How should I do that? 我该怎么办?


#1楼

参考:https://stackoom.com/question/qE1u/如何检测iPhone-宽屏设备


#2楼

First of all, you shouldn't rebuild all your views to fit a new screen, nor use different views for different screen sizes. 首先,您不应重建所有视图以适应新屏幕,也不应对不同屏幕尺寸使用不同视图。

Use the auto-resizing capabilities of iOS, so your views can adjust, and adapt any screen size. 使用iOS的自动调整大小功能,以便您的视图可以调整,并适应任何屏幕大小。

That's not very hard, read some documentation about that. 这不是很难,请阅读一些相关的文档 It will save you a lot of time. 它会为你节省很多时间。

iOS 6 also offers new features about this. iOS 6还提供了有关此功能的新功能。
Be sure to read the iOS 6 API changelog on Apple Developer website. 请务必阅读Apple Developer网站上的iOS 6 API更新日志
And check the new iOS 6 AutoLayout capabilities. 并检查新的iOS 6 AutoLayout功能。

That said, if you really need to detect the iPhone 5, you can simply rely on the screen size . 也就是说,如果你真的需要检测iPhone 5,你可以简单地依赖屏幕尺寸

[ [ UIScreen mainScreen ] bounds ].size.height

The iPhone 5's screen has a height of 568. iPhone 5的屏幕高度为568。
You can imagine a macro, to simplify all of this: 您可以想象一个宏,以简化所有这些:

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

The use of fabs with the epsilon is here to prevent precision errors, when comparing floating points, as pointed in the comments by H2CO3. 正如H2CO3的评论所指出的,在比较浮点时,使用带有epsilon的fabs可以防止精度错误。

So from now on you can use it in standard if/else statements: 所以从现在开始,你可以在标准的if / else语句中使用它:

if( IS_IPHONE_5 )
{}
else
{}

Edit - Better detection 编辑 - 更好的检测

As stated by some people, this does only detect a widescreen , not an actual iPhone 5. 正如一些人所说,这只能检测宽屏 ,而不是真正的iPhone 5。

Next versions of the iPod touch will maybe also have such a screen, so we may use another set of macros. iPod touch的下一个版本也可能有这样的屏幕,所以我们可能会使用另一组宏。

Let's rename the original macro IS_WIDESCREEN : 让我们重命名原始的宏IS_WIDESCREEN

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

And let's add model detection macros: 让我们添加模型检测宏:

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

This way, we can ensure we have an iPhone model AND a widescreen, and we can redefine the IS_IPHONE_5 macro: 这样,我们可以确保我们有一个iPhone型号一个宽屏幕,我们可以重新定义IS_IPHONE_5宏:

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

Also note that, as stated by @LearnCocos2D, this macros won't work if the application is not optimised for the iPhone 5 screen (missing the Default-568h@2x.png image), as the screen size will still be 320x480 in such a case. 另请注意,正如@ LearnCocos2D所述,如果应用程序未针对iPhone 5屏幕进行优化(缺少Default-568h@2x.png图像),则此宏将无法工作,因为屏幕大小仍为320x480一件事。

I don't think this may be an issue, as I don't see why we would want to detect an iPhone 5 in a non-optimized app. 我不认为这可能是一个问题,因为我不明白为什么我们想要在非优化的应用程序中检测iPhone 5。

IMPORTANT - iOS 8 support 重要信息 - iOS 8支持

On iOS 8, the bounds property of the UIScreen class now reflects the device orientation . 在iOS 8上, UIScreen类的bounds属性现在反映了设备方向
So obviously, the previous code won't work out of the box. 很明显,以前的代码不会开箱即用。

In order to fix this, you can simply use the new nativeBounds property, instead of bounds , as it won't change with the orientation, and as it's based on a portrait-up mode. 为了解决这个问题,您可以简单地使用新的nativeBounds属性而不是bounds ,因为它不会随方向而改变,因为它基于纵向模式。
Note that dimensions of nativeBounds is measured in pixels, so for an iPhone 5 the height will be 1136 instead of 568. 请注意, nativeBounds的尺寸以像素为单位,因此对于iPhone 5,高度将为1136而不是568。

If you're also targeting iOS 7 or lower, be sure to use feature detection, as calling nativeBounds prior to iOS 8 will crash your app: 如果您还要定位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 */
}

You can adapt the previous macros the following way: 您可以通过以下方式调整以前的宏:

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

And obviously, if you need to detect an iPhone 6 or 6 Plus, use the corresponding screen sizes. 显然,如果您需要检测iPhone 6或6 Plus,请使用相应的屏幕尺寸。


#3楼

I've taken the liberty to put the macro by Macmade into a C function, and name it properly because it detects widescreen availability and NOT necessarily the iPhone 5. 我冒昧通过Macmade把宏成C函数,因为它检测到宽屏的可用性不一定是iPhone 5的正确名字。

The macro also doesn't detect running on an iPhone 5 in case where the project doesn't include the Default-568h@2x.png . 如果项目不包含Default-568h@2x.png ,宏也不会检测到在iPhone 5上运行。 Without the new Default image, the iPhone 5 will report a regular 480x320 screen size (in points). 如果没有新的默认图像,iPhone 5将报告常规的480x320屏幕尺寸(以磅为单位)。 So the check isn't just for widescreen availability but for widescreen mode being enabled as well. 因此,检查不仅适用于宽屏可用性,还适用于宽屏模式

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

#4楼

Really simple solution 真的很简单的解决方案

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

#5楼

this is the macro for my cocos2d project. 这是我的cocos2d项目的宏。 should be the same for other apps. 对于其他应用应该是相同的。

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

#6楼

use the following Code: 使用以下代码:

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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值