Swift version of Objective C Macro : IS_IPHONE5 [duplicate] - iphone

This question already has answers here:
How should I replace these screen size and device type macros in Swift?
(3 answers)
Closed 7 years ago.
I need swift version of below Obj.C Macro
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE5 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0f)

Define these outside of a class tag
let IS_IPHONE = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Phone
let IS_IPHONE5 = IS_IPHONE && UIScreen.mainScreen().bounds.size.height == 568.0

Related

Xcode 5, How to build an app with UI compatible with IOS 6 as well as IOS 7 [duplicate]

This question already has an answer here:
iOS 6 UI distorted [closed]
(1 answer)
Closed 9 years ago.
I am using Xcode 5.
I want to build an app with UI compatible with both IOS 6 as well IOS 7. Can anyone help me with this. App should be compatible with iPhone (3gs), iPhone retina 3.5 and iPhone retina 4.
UI gets distorted when i watch it on iPhone (3GS) having IOS 6.
I have tried enabling Auto layout, But still the problem persists for some of the screens.
1: If you are using UINavigationController and your navigation bar is visible then this works
float systemVersion=[[[UIDevice currentDevice]systemVersion]floatValue];
if(systemVersion >=7.0f)
{
self.edgesForExtendedLayout=UIRectEdgeNone;
}
OR
You can also set from stoyboard
2: Another solution is . You can use IOS 6/7 Deltas
i) take new view and setting its Y postion is 20
ii) move all control into this view
iii)setting new view Detas Y Property is -20
Now you view hirerachy is look like as
You can see in follwing image how to set Deltas property
There are several macros which are helpful in this case
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
#define APP_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"] compare:v options:NSNumericSearch] != NSOrderedAscending)
To see is your iOS version is greater than iOS7:
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
// iOS 7 specific instruction
}
However is this IF-ELSE is still long, you can do something like this
#define IS_IOS_7 SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")
and then
if (IS_IOS_7) {
// instruction...
}

How to check the device is iPhone 5? [duplicate]

This question already has answers here:
How to detect iPhone 5 (widescreen devices)?
(24 answers)
Closed 9 years ago.
How can I check if an application running on iPhone 5 or not and then do something?
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
then in the code:
if (IS_IPHONE_5) {
//is iphone 5
}
You're likely concerned with the window size, not the make/model, this will do:
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
if (screenRect.size.height == 568)
{
// this is an iPhone 5+
}
You can do it with checking screen resolution or you can do it with using:
#import "sys/utsname.h"
which give you identifier for each device. Just see my answer here: recognize device
Using screen is fine.
#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.0f)
No epsilon check is required
We can directly put this method in constant file and can use any where using define
#define ISIPHONE5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
#define HEIGHT (ISIPHONE5 ? 60:145)
Or can use
#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)
We can also check IOS via below
#define IOS_OLDER_THAN_6 ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0 )
#define IOS_NEWER_OR_EQUAL_TO_6 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0 )
You can check your device's iOS version if is 6.0 then its a iPhone 5.....
Here's the code..
double osVersion = [[[UIDevice currentDevice] systemVersion] doubleValue];
NSLog(#"OSVersion: %f", osVersion);
if (osVersion == 6.0)
{
//Paste your code here.....
}

Best way to detect the device is iPhone 5 [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to detect iPhone 5 (widescreen devices)?
Does anybody know a better way to detect whether the device is an iPhone 5 than checking the screen height?
[UIScreen mainScreen].bounds.size.height == 568.0;
Thanks in advance.
I use the following macro:
#define IS_IPHONE ( [[[UIDevice currentDevice] model] isEqualToString:#"iPhone"] )
#define IS_HEIGHT_GTE_568 [[UIScreen mainScreen ] bounds].size.height >= 568.0f
#define IS_IPHONE_5 ( IS_IPHONE && IS_HEIGHT_GTE_568 )
And then i can do:
if(IS_IPHONE_5)
{
NSLog(#"i am an iPhone 5!");
}
else
{
NSLog(#"This is not an 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.
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?
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.
Be sure to read the iOS 6 API changelog on Apple Developer website.
And check the new iOS 6 AutoLayout capabilities.
That said, if you really need to detect the iPhone 5, you can simply rely on the screen size.
[ [ UIScreen mainScreen ] bounds ].size.height
The iPhone 5's screen has a height of 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.
So from now on you can use it in standard if/else statements:
if( IS_IPHONE_5 )
{}
else
{}
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:
#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:
#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.
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 the UIScreen 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 of bounds, 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:
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.
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
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
}
}
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
#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)
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.
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
}
}
We now need to account for iPhone 6 and 6Plus screen sizes. Here's an updated answer
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
}
Some useful info
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"
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.
The macro also doesn't detect running on an iPhone 5 in case where the project doesn't include the Default-568h#2x.png. Without the new Default image, the iPhone 5 will report a regular 480x320 screen size (in points). 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);
}
Here is our codes, test passed on ios7/ios8 for iphone4,iphone5,ipad,iphone6,iphone6p, no matter on devices or simulator:
#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 )
I used hfossli's answer and translated it to 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)
this is the macro for my cocos2d project. 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))
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
// This is iPhone 5 screen
} else {
// This is iPhone 4 screen
}
In Swift, iOS 8+ project I like to make an extension on UIScreen, like:
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;
}
}
(NOTE: nativeBounds is in pixels).
And then the code will be like:
if UIScreen.mainScreen().isPhone4 {
// do smth on the smallest screen
}
So the code makes it clear that this is a check for the main screen, not for the device model.
Borrowing from Samrat Mazumdar's answer, here's a short method that estimates the device screen size. It works with the latest devices, but may fail on future ones (as all methods of guessing might). It will also get confused if the device is being mirrored (returns the device's screen size, not the mirrored screen size)
#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
}
}
I think it should be good if this macro will work in device and simulator, below are the solution.
#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)
I found that answers do not include a special case for Simulators.
#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 )
+(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;
}
This has been answered a hundred times but this solution worked the best for me and helped address the issue when new devices are introduced and I don't have a size defined.
Swift 5 Helper:
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
}
}
}
This is because it's easy to memorize a phone's inch sizes, like, "5.5 inch" or "4.7 inch" device but difficult to remember the exact pixel sizes.
if UIScreen.main.phoneSizeInInches() == 4 {
//do something with only 4 inch iPhones
}
This also gives you the opportunity to do something like this:
if UIScreen.main.phoneSizeInInches() < 5.5 {
//do something on all iPhones smaller than the plus
}
The default: tries to uses the screen size and scale to try and calculate the diagonal inches. This is in case some new device size appears, it will try its best to determine and code, such as the last example, should still work.
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
}
Relying in the size is wrong in so many levels. How about we ask to the system?
- (NSString *) getDeviceModel
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}
Taken from Best way to detect hardware type, iPhone4 or iPhone5?, edzio27 answer.
This way you can detect device family.
#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
If the project is created using Xcode 6, then use the below mentioned code to detect the devices..
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");
}
If the project was created in Xcode 5 and opened in Xcode 6, then use the below mentioned code to detect the devices.(This code works if no launching images for iPhone 6,6+ are assigned)
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;
}
If you are still using Xcode 5 all together then use the following code to detect the devices (iPhone 6 and 6+ will not be detected)
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");
}
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
}
In Swift 3 you can use my simple class KRDeviceType.
https://github.com/ulian-onua/KRDeviceType
It well documented and supports operators ==, >=, <=.
For example to detect if device has bounds of iPhone 6/6s/7, you can just use next comparison:
if KRDeviceType() == .iPhone6 {
// Perform appropiate operations
}
To detect if device has bounds of iPhone 5/5S/SE or earlier (iPhone 4s) you can use next comparison:
if KRDeviceType() <= .iPhone5 { //iPhone 5/5s/SE of iPhone 4s
// Perform appropiate operations (for example, set up constraints for those old devices)
}
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
}
Here is the correct test of the device, without depending on the orientation
- (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;
}
Used to detect iPhone and iPad Devices of all versons.
#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)

ifdef syntax doesn't work

I want dynamically define a constant based on the different device heights.
I tried to use this code but it doesn't work:
#define isPhone568 ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height == 568)
#ifdef isPhone568
#define kColumnHeightPortrait568 548
#else
#define kColumnHeightPortrait568 (IS_IPAD ? 984 : 460)
#endif
Even if i'm using the 3.5" simulator, i get 548. What's wrong with this?
You can't run code in macro definitions, it's a simple text substitution process that happens at compile-time. Hence you have no idea what the device characteristics are at that point, because you're not on the target device.
If you want to use something like [UIDevice currentDevice] userInterfaceIdiom, you have to evaluate it at run-time, not in a compile-time macro, something like:
int kColumnHeightPortrait568 = 548;
if (([[UIDevice currentDevice] userInterfaceIdiom] != UIUserInterfaceIdiomPhone)
|| ([UIScreen mainScreen].bounds.size.height != 568))
{
kColumnHeightPortrait568 = (IS_IPAD ? 984 : 460);
}
The #ifdef is used to check whether a macro is defined. As you define isPhone568 in the first line, #ifdef isPhone568 will be true.
If you want to test the value of an expression rather than the existance of a macro, you should use #if instead. But #if can test no more than the simple arithmetic expression, just as paxdiablo mentioned, "You can't run code in macro definitions".