提问人:Finn Gaida 提问时间:9/16/2012 最后编辑:General GrievanceFinn Gaida 更新时间:6/9/2023 访问量:155942
如何检测iPhone 5(宽屏设备)?
How to detect iPhone 5 (widescreen devices)?
问:
我刚刚升级到 Xcode 4.5 GM,发现您现在可以在情节提要中将“4 英寸视网膜”大小应用于视图控制器。
现在,如果我想创建一个同时在 iPhone 4 和 iPhone 5 上运行的应用程序,我当然必须为每个窗口构建两次,但我还必须检测用户使用的是 3.5 英寸还是 4 英寸屏幕的 iPhone,然后应用视图。
我应该怎么做?
答:
首先,不应重新生成所有视图以适应新屏幕,也不应为不同的屏幕大小使用不同的视图。
使用 iOS 的自动调整大小功能,以便您的视图可以调整和调整任何屏幕尺寸。
这不是很难,请阅读一些有关这方面的文档。这将为您节省大量时间。
iOS 6 还提供了相关的新功能。
请务必阅读 Apple 开发者网站上的 iOS 6 API 更新日志。
并检查新的 iOS 6 自动布局功能。
也就是说,如果你真的需要检测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 )
在这里使用 with the epsilon 是为了防止在比较浮点时出现精度误差,正如 H2CO3 的评论中所指出的那样。fabs
因此,从现在开始,您可以在标准的 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 屏幕(缺少 [email protected] 图像)进行优化,则此宏将不起作用,因为在这种情况下,屏幕尺寸仍将为 320x480。
我不认为这可能是一个问题,因为我不明白为什么我们要在未优化的应用程序中检测iPhone 5。
重要 - iOS 8 支持
在 iOS 8 上,类的属性现在反映设备方向。
所以很明显,以前的代码不会开箱即用。bounds
UIScreen
为了解决此问题,您可以简单地使用 new 属性,而不是 ,因为它不会随方向而变化,并且它基于纵向模式。
请注意,尺寸以像素为单位,因此对于 iPhone 5,高度将为 1136 而不是 568。nativeBounds
bounds
nativeBounds
如果您还以 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 */
}
您可以按以下方式调整以前的宏:
#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,请使用相应的屏幕尺寸。
评论
#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
DBL_EPSILON
==
1.0/3.0*3.0
我冒昧地将 Macmade 的宏放入 C 函数中,并正确命名它,因为它检测宽屏可用性,而不一定是 iPhone 5。
如果项目不包含 [email protected],则宏也不会检测到在 iPhone 5 上运行。如果没有新的默认图像,iPhone 5 将报告常规的 480x320 屏幕尺寸(以磅为单位)。因此,检查不仅针对宽屏可用性,还针对启用的宽屏模式。
BOOL isWidescreenEnabled()
{
return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height -
(double)568) < DBL_EPSILON);
}
评论
inline
非常简单的解决方案
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
CGSize result = [[UIScreen mainScreen] bounds].size;
if(result.height == 480)
{
// iPhone Classic
}
if(result.height == 568)
{
// iPhone 5
}
}
评论
这是我的 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))
使用以下代码:
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
}
借用 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
}
}
评论
针对 SDK 和操作系统的任意组合进行测试和设计:
迅速
添加了 iPad 类型。 iPad 2 和 iPad mini 是非视网膜 iPad。iPad Mini 2 及更高版本、iPad 3、4、iPad Air、Air 2、Air 3 和 iPad Pro 9.7 的逻辑分辨率相同,均为 1024。iPad Pro 的最大长度为 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是本例中所需的结果。
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)
注意:例如,如果 iPhone 6 处于缩放模式,则 UI 是 iPhone 5 的放大版本。这些功能不是确定设备类型,而是显示模式,因此iPhone 5是本例中所需的结果。
评论
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)
SCREEN_MAX_LENGTH
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
}
我认为如果这个宏可以在设备和模拟器中工作,那应该很好,下面是解决方案。
#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)
在很多层面上,依赖大小是错误的。我们向系统询问怎么样?
- (NSString *) getDeviceModel
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}
摘自检测硬件类型的最佳方法,iPhone4 或 iPhone5?,edzio27 答案。
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
// This is iPhone 5 screen
} else {
// This is iPhone 4 screen
}
我发现答案不包括模拟器的特例。
#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 )
这样,您可以检测设备系列。
#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
+(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;
是不必要的,因为如果不更改变量,则该变量已经具有该值
我们现在需要考虑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和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)
评论
IS_RETINA
@1x
@3x
如果项目是使用 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");
}
这是我们的代码,在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 )
评论
我使用了 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)
添加“新的 Swift 文件”->
AppDelegateEx.swift
将扩展添加到
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 } }
用法:
if AppDelegate.isIPhone5() { collectionViewTopConstraint.constant = 2 }else if AppDelegate.isIPhone6() { collectionViewTopConstraint.constant = 20 }
这是对设备的正确测试,不依赖于方向
- (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;
}
在 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
}
因此,代码清楚地表明,这是对主屏幕的检查,而不是对设备型号的检查。
这个问题已经回答了一百次,但这个解决方案对我来说效果最好,并且帮助解决了引入新设备并且我没有定义大小时的问题。
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 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
}
}
}
这是因为很容易记住手机的英寸尺寸,例如“5.5 英寸”或“4.7 英寸”设备,但很难记住确切的像素尺寸。
if UIScreen.main.phoneSizeInInches() == 4 {
//do something with only 4 inch iPhones
}
这也使你有机会做这样的事情:
if UIScreen.main.phoneSizeInInches() < 5.5 {
//do something on all iPhones smaller than the plus
}
默认值:尝试使用屏幕大小和比例来尝试计算对角线英寸。这是为了以防出现一些新的设备尺寸,它将尽力确定,并且代码(例如最后一个示例)仍然应该有效。
在 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)
}
评论