iOS--iPhoneX设备判断
iPhone的设备类型越来越多,
iPhone各代设备一览:
设备名 | 设备标识 | 分辨率 | 屏幕尺寸 | 屏幕模式 | 上市时间 |
---|---|---|---|---|---|
iPhone初号机 | iPhone1,1 | 320*480 | 3.5(inch) | 1x | 2007-5-29 |
iPhone 3 | iPhone1,2 | 320*480 | 3.5(inch) | 1x | 2008-6-11 |
iPhone 3GS | iPhone2,1 | 320*480 | 3.5(inch) | 1x | 2009-5-19 |
iPhone 4 | iPhone3,1/iPhone3,2/iPhone3,3 | 640*960 | 3.5(inch) | 2x | 2010-6/2010-10 |
iPhone 4s | iPhone4,1 | 640*960 | 3.5(inch) | 2x | 2011-10-4 |
iPhone 5 | iPhone5,1/iPhone5,2 | 640*1136 | 4.0(inch) | 2x | 2012-12-12 |
iPhone 5c | iPhone5,3/iPhone5,4 | 640*1136 | 4.0(inch) | 2x | 2012-12-12 |
iPhone 6 | iPhone7,2 | 750*1334 | 4.7'' | 2x | 2014-9-9 |
iPhone 6 Plus | iPhone7,1 | 1080*1920 | 5.5'' | 3x | 2014-9-9 |
iPhone 6s | iPhone8,1 | 750*1334 | 4.7'' | 2x | 2015-9-9 |
iPhone 6s Plus | iPhone8,2 | 750*1334 | 5.5'' | 3x | 2015-9-9 |
iPhone SE(1st generation) | iPhone8,4 | 640*1136 | 4.0'' | 2x | 2016-3 |
iPhone 7 | iPhone9,1/Phone9,3 | 750*1334 | 4.7'' | 2x | 2016-9-7 |
iPhone 7 Plus | iPhone9,2/ iPhone9,4 | 1080*1920 | 5.5'' | 3x | 2016-9-7 |
iPhone 8 | iPhone10,1/iPhone10,4 | 750*1334 | 4.7'' | 2x | 2017-12-12 |
iPhone 8 Plus | iPhone10,2/iPhone10,5 | 1080*1920 | 5.5'' | 3x | 2017-12-12 |
iPhone X | iPhone10,3/iPhone10,6 | 1125*2436 | 5.8'' | 2x | 2017-12-12 |
iPhone XR | iPhone11,8 | 1125*2436 | 5.8'' | 3x | 2017-12-12 |
iPhone XS | iPhone11,2 | 1125*2436 | 5.8'' | 3x | 2018-9-21 |
iPhone XS Max | iPhone11,4/iPhone11,6 | 1125*2436 | 6.5'' | 3x | 2018-9-12 |
iPhone 11 | iPhone12,1 | 828*1792 | 5.8'' | 3x | 2019-9-10 |
iPhone 11 Pro | iPhone12,3 | 1125*2430 | 5.8'' | 3x | 2019-9-10 |
iPhone 11 Pro Max | iPhone12,5 | 1242*2680 | 6.5'' | 3x | 2019-9-10 |
iPhone SE(2ed generation) | iPhone12,8 | 750*1334 | 4,.7'' | 2x | 2019-9-10 |
其中iPhoneX之前,屏幕分辨率是很好识别的除了比较老的机型(iPhone1-iPhone3GS)3.5‘’是320480分辨率,4.0''是640960,4.7‘’是7501344,5.5''是10801920.基本能记得住,分得清。iPhoneX之后,实在是记不住喽。所以做适配时有必要做区分。
1、检测iPhoneX/XS/XR 设备的几种方式
//
// Tools.m
// ThirdLibPro
//
// Created by wjwdive on 2020/6/10.
// Copyright © 2020 wjwdive. All rights reserved.
//
#import "Tools.h"
#import <sys/sysctl.h>
#import <sys/utsname.h>
// 指纹解锁必须的头文件
#import <LocalAuthentication/LocalAuthentication.h>
/**
iPhoneX 开发尺寸
iPhone XS: 5.8 英寸,375pt * 812pt (@3x);
iPhone XR: 6.1 英寸,414pt * 896pt (@2x);
iPhone XS Max: 6.5 英寸,414pt * 896pt (@3x);
*/
@implementation Tools
/// 根据分辨率判断是否是刘海屏设备,以下两种情况不适用
// 缺陷1: 在APP支持横竖屏切换时,
// 缺陷2: 在模拟器调试时,能够正确判断当前所选择的模拟器是不是iPhoneX
+ (BOOL)isiPhoneX {
//iPhone X/XS: 375pt * 812pt(@3x)
//iPhone XS Max: 414pt * 896pt(@3x)
//iPhone XR : 414pt * 896(@2x)
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
if (screenHeight == 812.0f || screenHeight == 896.0f) {
return YES;
}
return NO;
}
//通过deviceMoel 来判断
//缺陷,在模拟器里获得的是i386,或 x86_64
//获取device model/ machine name 的方法2
+ (NSString *)machineName1 {
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = (char *)malloc(size);
if (machine == NULL) {
return nil;
}
sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *platform = [NSString stringWithCString:machine encoding:NSUTF8StringEncoding];
free(machine);
return platform;
}
//获取device model/ machine name 的方法2
+ (NSString *)machineName2 {
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}
//在模拟器里可以用下面的方法正确获取模拟器对应的device model
+ (NSString *)machineSimulator {
NSString *model = NSProcessInfo.processInfo.environment[@"SIMULATOR_MODEL_IDENTIFIER"];
return model;
}
//综上,我们的方法
+ (BOOL)isiPhoneXFull {
static BOOL isiPhone = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
#if TARGET_IPHONE_SIMULATOR
//获取模拟器对应的DeviceModel
NSString *model = NSProcessInfo.processInfo.environment[@"SIMULATOR_MODEL_IDENTIFIER"];
#else
//获取真机设备的 device model
struct utsname systemInfo;
uname(&systemInfo);
NSString *model [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
#endif
//判断device model是否为 “iPhone10,3” 和 “iPhone10,6”,或者以“iPhone11开头”
isiPhone = [model isEqualToString:@"iPhone10,3"] || [model isEqualToString:@"iPhone10,6"] || [model hasPrefix:@"iPhone11,"];
});
return isiPhone;
}
//通过屏幕的宽高【开发尺寸】而非分辨率来判断
/**
iphoneX 刘海屏只有两种开发尺寸。一般屏幕(X, XR, XS): 375pt*812pt 大屏幕(XR Max ):414pt * 896pt.
如果APP只支持竖屏,那么宽高值大的就是高度,根据高度如果等于 812pt,或者896pt 就可以判断是iPhoneX系列的刘海屏
如果APP要支持横竖屏,就要考虑还有一个手机平放的时候获取不到横竖屏幕的值,UIDevice中提供了一个朝向的属性orientation(横向,竖向,水平),若要考虑设备处于横屏或者竖屏,然后分别取对应的屏幕宽度(横屏)或者高度(竖屏)来判断,但是当这个属性的值为FaceUp或者FaceDown(设备水平放置),是无法知道设备的横屏还是竖屏。
*/
//我们只需要获取屏幕的宽度和高度,取较大的一方比较是否等于 812或者 896,若有一个相等,就是iPhoneX系列的屏幕
+ (BOOL)isiPhoneXByHeight {
//判断当前设备是否为iPhone 或 iPod touch
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
//获取屏幕的宽度和高度, 取较大一方进行比较是否等于 812.0 或者 896.0
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
CGFloat maxLength = screenWidth > screenHeight ? screenWidth : screenHeight;
if (maxLength == 812.0f || maxLength == 896.f) {
return YES;
}
}
return NO;
}
// 通过底部安全区域来判断(iOS11 之后引入了安全区域的概念)
/*
iPhone X在竖屏下,keyWindow的safeAreaInsets值为
{top: 44, left: 0, bottom: 34, right: 0}
在横屏下:
{top: 0, left: 44, bottom: 21, right: 44}
因此我们可以通过判断 safeAreaInsets 的 bottom是否等于 34.0 或者 21.0 来判断设备是否是 iPhone X,因为其他设备对应的bottm横竖屏Inset都为0
缺陷:1、iOS 11之后。2、该方法必须在 window初始化之后才可以使用,也就是didFinishLaunchingWithOptions的回调中才能判断
*/
+ (BOOL)isiPhoneByBottomInset {
if (@available(iOS 11.0, *)) {
UIWindow *keyWindow = [[[UIApplication sharedApplication] delegate] window];
//获取底部安全区域高度, iPhone X 竖屏下为34.0,横屏下为21.0 其他设备都为0
CGFloat bottomSafeInset = keyWindow.safeAreaInsets.bottom;
if (bottomSafeInset == 34.0 || bottomSafeInset == 21.0) {
return YES;
}
}
return NO;
}
//通过UIStateBar的高度来判断
/**
在iPhoneX 之前,所有iPhone设备的StatusBar 状态栏高度都为20.0pt, 而iPhoneX 的为44pt, 因此我们可以根据状态栏是哦符等于44 .0 来判断
不足:该方法只适用于竖屏切状态栏显示的情况下才能正确检测,而在横屏模式下,或者App 隐藏导航栏时,获取到的状态栏高度都为0 (StatusBarFrame 的值为 CGRectZero )
*/
+ (BOOL)isiPhoneByStatusBarHeight {
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
if (statusBarFrame.size.height == 44.0f) {
return YES;
}
return NO;
}
//通过是否支持FaceID 判断
/**
只有刘海屏的iPhoneX 设备才支持 FaceID ,因此我们可以通过判断设备是否支持FaceID 来判断
缺陷:如果用户禁用 面部解锁, canEvaluatePolicy:error: 方法的使用将无法正确的判断,而且也不适用于模拟器中判断
*/
+ (BOOL)isiPhoneByFaceID {
if (@available(iOS 11.0, *)) {
//
LAContext *contex = [[LAContext alloc] init];
if ([contex canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil]) {
return (contex.biometryType == LABiometryTypeFaceID);
}
}
return NO;
}
@end