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

2、

posted @ 2020-06-10 18:12  wjwdive  阅读(2853)  评论(0编辑  收藏  举报