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.
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.
How should I do that?
this is the macro for my cocos2d project. should be the same for other apps.
In Swift, iOS 8+ project I like to make an extension on
UIScreen
, like:(NOTE:
nativeBounds
is in pixels).And then the code will be like:
So the code makes it clear that this is a check for the main screen, not for the device model.
I found that answers do not include a special case for Simulators.
use the following Code:
Tested and designed for any combination of SDK and OS:
Swift
Added iPad types. iPad 2 and iPad mini are non-retina iPads. While iPad Mini 2 & above, iPad 3, 4, iPad Air, Air 2, Air 3, and iPad Pro 9.7 have same logical resolution of 1024. iPad Pro has maxLength of 1366. Reference
See it in action https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346
Note: If e.g. iPhone 6 is in zoomed mode the UI is a zoomed up version of iPhone 5. These functions is not determining device type, but display mode thus iPhone 5 is the desired result in this example.
Objective-C
Usage: http://pastie.org/9687735
Note: If e.g. iPhone 6 is in zoomed mode the UI is a zoomed up version of iPhone 5. These functions is not determining device type, but display mode thus iPhone 5 is the desired result in this example.
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.
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, but this is still under NDA at the moment.
Be sure to read the API changelog on Apple Developer website, if you can access to it.
Edit: As iOS 6 is now out, check the new AutoLayout capabilities.
That said, if you really need to detect the iPhone 5, you can simply rely on the screen size.
The iPhone 5's screen has a height of 568.
You can imagine a macro, to simplify all of this:
The use of
fabs
with the epsilon is here to prevent precision errors, when comparing floating points, as pointed in the comments by H2CO3.So from now on you can use it in standard if/else statements:
Edit - Better detection
As stated by some people, this does only detect a widescreen, not an actual iPhone 5.
Next versions of the iPod touch will maybe also have such a screen, so we may use another set of macros.
Let's rename the original macro
IS_WIDESCREEN
:And let's add model detection macros:
This way, we can ensure we have an iPhone model AND a widescreen, and we can redefine the
IS_IPHONE_5
macro: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.
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.
IMPORTANT - iOS 8 support
On iOS 8, the
bounds
property of theUIScreen
class now reflects the device orientation.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 ofbounds
, as it won't change with the orientation, and as it's based on a portrait-up mode.Note that dimensions of
nativeBounds
is measured in pixels, so for an iPhone 5 the height will be 1136 instead of 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:You can adapt the previous macros the following way:
And obviously, if you need to detect an iPhone 6 or 6 Plus, use the corresponding screen sizes.
Final note
Comments and suggestions have been incorporated in this post.
Thanks to everybody.