截止目前,苹果所有刘海系列的设备屏幕数据如下:

  • iPhone X 、iPhone XS: 5.8英寸, 375pt * 812pt(@3x),启动图1125px * 2436px
  • iPhone XR: 6.1英寸, 414pt * 896pt(@2x),启动图828px * 1792px
  • iPhone XS Max: 6.5英寸, 414pt * 896pt(@3x),启动图1242px * 2688px

该系列设备导航栏高度88(64), 状态栏高度44(20), tabbar高度83(49), 其中括号中的为非刘海系列的高度。

对于未进行新设备屏幕尺寸适配的工程,在新设备iPhone XS Max和iPhone XR上运行, 它们是以放大模式自动适配的(以iPhone X为基准等比例放大),此时在代码中获取的屏幕高度都是375pt * 812pt。

针对这种情况,需要配置Assets.xcassets 里的 LaunchImage,新增两种828px * 1792px1242px * 2688px启动图即可。

对于比较新的以LaunchScreen.stroyboard为启动页的,据说是直接重新编译工程即可。

最后,对于刘海屏幕的判断,项目中使用了两种方式:

  1. 根据屏幕宽高进行判断:

    这是RN中用来判断的代码,使用nativeBounds是由于它是一个跟屏幕朝向无关的数据,值恒等于屏幕portrait-up方向时的宽高。

    static BOOL RCTIsIPhoneX() {
      static BOOL isIPhoneX = NO;
      static dispatch_once_t onceToken;
    
      dispatch_once(&onceToken, ^{
        CGSize screenSize = [UIScreen mainScreen].nativeBounds.size;
        CGSize iPhoneXScreenSize = CGSizeMake(1125, 2436);
        CGSize iPhoneXMaxScreenSize = CGSizeMake(1242, 2688);
        CGSize iPhoneXRScreenSize = CGSizeMake(828, 1792);
    
        isIPhoneX =
        CGSizeEqualToSize(screenSize, iPhoneXScreenSize) ||
        CGSizeEqualToSize(screenSize, iPhoneXMaxScreenSize) ||
        CGSizeEqualToSize(screenSize, iPhoneXRScreenSize);
      });
    
      return isIPhoneX;
    }
    
  2. 通过获取设备的device model来判断:

    每一台iOS设备都有对应的硬件编码/标识符,称为device model 或者叫machine name,代码如下

    + (NSString *)getMachine
    {
    	//方法一:
    //    static const char MachineName[] = "hw.machine";
    //    NSString* result = nil;
    //    size_t size = 0;
    //    if (sysctlbyname(MachineName, NULL, &size, NULL, 0) || size == 0)
    //        return nil;
    //    char *machine = new char[size];
    //    if (sysctlbyname(MachineName, machine, &size, NULL, 0) == 0)
    //        result = [NSString stringWithUTF8String:machine];
    //    delete[] machine;
    //    return result;
    
        方法二:添加了对于模拟器的支持
        static NSString *model;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
    
    #if TARGET_IPHONE_SIMULATOR
    #ifdef DEBUG
            // 获取模拟器所对应的 device model
            model = NSProcessInfo.processInfo.environment[@"SIMULATOR_MODEL_IDENTIFIER"];
    #endif
    #else
            // 获取真机设备的 device model
            struct utsname systemInfo;
            uname(&systemInfo);
            model = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
    #endif
        });
        return model;
    }
    

    到此我们就可以根据device model来判断是否是iPhone X了:

    + (bool) isIphoneX
    {
        NSString* model = [self getMachine];
        BOOL isiPhoneX = [model isEqualToString:@"iPhone10,3"] || [model isEqualToString:@"iPhone10,6"] || [model hasPrefix:@"iPhone11,"];
    
        return isiPhoneX;
    }
    

去年发布的第一代 iPhone X 对应的 device mode 为 iPhone10,3iPhone10,6,而今年最新发布 iPhone XS 对应 iPhone11,2,iPhone XS Max 对应 iPhone11,4iPhone11,6,iPhone XR 对应 iPhone11,8,完整的 device mode 数据参考这里:https://www.theiphonewiki.com/wiki/Models

另外对于各个屏幕的分辨率,可以参考这张图:iphone X系列设配屏幕适配-LMLPHP

参考链接:

04-14 01:53