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 a
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 )
Tested and designed for any combination of SDK and OS:
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.
#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.
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
}
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.
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.
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)
}