React Native 判断 iOS 设备是否具有刘海屏的几种方法

React Native 2021-03-31 阅读 48 评论 0

iPhone 的刘海屏,是2018年在 iOS 11 才出现,使用 React Native 判断 iOS 设备是否为刘海屏,下面介绍了2种方法。

1. 通过设备型号判断

使用第三方 react-native-device-infohasNotch() 方法,判断是否具有刘海屏,适用与安卓和 iOS。查看 deviceinfo.js 的源代码,找到 hasNotch() 方法,可以看到 devicesWithNotch 变量,列出了所有具有刘海屏的品牌和设备。如下:

const devicesWithNotch = [
  {
    brand: 'Apple',
    model: 'iPhone 11',
  },
  {
    brand: 'Apple',
    model: 'iPhone 11 Pro',
  },
  {
    brand: 'Apple',
    model: 'iPhone 11 Pro Max',
  },
  {
    brand: 'Apple',
    model: 'iPhone X',
  },
  {
    brand: 'Apple',
    model: 'iPhone XS',
  },
  {
    brand: 'Apple',
    model: 'iPhone XS Max',
  },
  {
    brand: 'Apple',
    model: 'iPhone XR',
  },
  {
    brand: 'Asus',
    model: 'ZenFone 5',
  },
  {
    brand: 'Asus',
    model: 'ZenFone 5z',
  },
  {
    brand: 'google',
    model: 'Pixel 3 XL',
  },
  {
    brand: 'Huawei',
    model: 'P20',
  },
  {
    brand: 'Huawei',
    model: 'P20 Plus',
  },
  {
    brand: 'Huawei',
    model: 'P20 Lite',
  },
  {
    brand: 'Huawei',
    model: 'ANE-LX1',
  },
  {
    brand: 'Huawei',
    model: 'INE-LX1',
  },
  {
    brand: 'Huawei',
    model: 'Honor 10',
  },
  {
    brand: 'Huawei',
    model: 'Mate 20 Lite',
  },
  {
    brand: 'Huawei',
    model: 'Mate 20 Pro',
  },
  {
    brand: 'Huawei',
    model: 'P30 Lite',
  },
  {
    brand: 'Huawei',
    model: 'P30 Pro',
  },
  {
    brand: 'Huawei',
    model: 'Nova 3',
  },
  {
    brand: 'Huawei',
    model: 'Nova 3i',
  },
  {
    brand: 'Leagoo',
    model: 'S9',
  },
  {
    brand: 'LG',
    model: 'G7',
  },
  {
    brand: 'LG',
    model: 'G7 ThinQ',
  },
  {
    brand: 'LG',
    model: 'G7+ ThinQ',
  },
  {
    brand: 'LG',
    model: 'LM-Q910', //G7 One
  },
  {
    brand: 'LG',
    model: 'LM-G710', //G7 ThinQ
  },
  {
    brand: 'LG',
    model: 'LM-V405', //V40 ThinQ
  },
  {
    brand: 'Motorola',
    model: 'Moto g7 Play',
  },
  {
    brand: 'Motorola',
    model: 'Moto g7 Power',
  },
  {
    brand: 'Motorola',
    model: 'One',
  },
  {
    brand: 'Nokia',
    model: '5.1 Plus',
  },
  {
    brand: 'Nokia',
    model: '6.1 Plus',
  },
  {
    brand: 'Nokia',
    model: '7.1',
  },
  {
    brand: 'Nokia',
    model: '8.1',
  },
  {
    brand: 'OnePlus',
    model: '6',
  },
  {
    brand: 'OnePlus',
    model: 'A6003',
  },
  {
    brand: 'ONEPLUS',
    model: 'A6000',
  },
  {
    brand: 'OnePlus',
    model: 'OnePlus A6003',
  },
  {
    brand: 'OnePlus',
    model: 'ONEPLUS A6010',
  },
  {
    brand: 'OnePlus',
    model: 'ONEPLUS A6013',
  },
  {
    brand: 'OnePlus',
    model: 'ONEPLUS A6000',
  },
  {
    brand: 'Oppo',
    model: 'R15',
  },
  {
    brand: 'Oppo',
    model: 'R15 Pro',
  },
  {
    brand: 'Oppo',
    model: 'F7',
  },
  {
    brand: 'Oukitel',
    model: 'U18',
  },
  {
    brand: 'Sharp',
    model: 'Aquos S3',
  },
  {
    brand: 'Vivo',
    model: 'V9',
  },
  {
    brand: 'Vivo',
    model: 'X21',
  },
  {
    brand: 'Vivo',
    model: 'X21 UD',
  },
  {
    brand: 'xiaomi',
    model: 'MI 8',
  },
  {
    brand: 'xiaomi',
    model: 'MI 8 Explorer Edition',
  },
  {
    brand: 'xiaomi',
    model: 'MI 8 SE',
  },
  {
    brand: 'xiaomi',
    model: 'MI 8 UD',
  },
  {
    brand: 'xiaomi',
    model: 'MI 8 Lite',
  },
  {
    brand: 'xiaomi',
    model: 'POCO F1',
  },
  {
    brand: 'xiaomi',
    model: 'POCOPHONE F1',
  },
  {
    brand: 'xiaomi',
    model: 'Redmi 6 Pro',
  },
  {
    brand: 'xiaomi',
    model: 'Redmi Note 7',
  },
  {
    brand: 'xiaomi',
    model: 'Mi A2 Lite',
  },
];

2. 自定义本地模块

创建本地自定义模块,判断 window.safeAreaInsets.bottom 值是否大于 0 来决定是否为刘海屏,导出常量,代码如下。

  • Objective C

NotchNative.h 文件

//  NotchNative.h

#import <React/RCTBridgeModule.h>
@interface NotchNative : NSObject <RCTBridgeModule>

@end

NotchNative.m 文件

// NotchNative.m

#import "NotchNative.h"
#import <UIKit/UIKit.h>

@implementation NotchNative

// To export a module named RCTCalendarModule
RCT_EXPORT_MODULE();

- (NSDictionary *)constantsToExport
{
  NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
  BOOL isBangsScreen = NO;
  CGFloat topPadding = 0;
  CGFloat bottomPadding = 0;
  if (@available(iOS 11.0, *)) {
    UIWindow *window = [[UIApplication sharedApplication].windows firstObject];
    topPadding = window.safeAreaInsets.top;
    bottomPadding = window.safeAreaInsets.bottom;
    isBangsScreen = bottomPadding > 0;
  }
  [dictionary setObject:[NSNumber numberWithInt:isBangsScreen] forKey:@"isBangsScreen"];
  [dictionary setObject:[NSNumber numberWithFloat:topPadding] forKey:@"topPadding"];
  [dictionary setObject:[NSNumber numberWithFloat:bottomPadding] forKey:@"bottomPadding"];
  return dictionary;
}

@end
  • Reactjs
import { NativeModules, Platform } from 'react-native'

if (Platform.OS === "ios") {
    const notchModule = NativeModules.NotchNative;
    console.log({notchModule});
    const data = {
        isBangsScreen: notchModule.isBangsScreen,
        topPadding: notchModule.topPadding,
        bottomPadding: notchModule.bottomPadding
    };
    console.log(data);
}
最后更新 2021-03-31