适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr屏幕尺寸及安全区域

2,524 阅读3分钟
  1. 先来认识pxpt区别 px就是表示pixel像素,是屏幕上显示数据的最基本的点,它不是自然界的长度单位,点的大小是会变的,也称为相对长度pt就是point,是印刷行业常用单位,等于1/72英寸,所以它是一个自然界标准的长度单位,也称为绝对长度

  2. 我们再来了解缩放因子(scale factor between logic point and device pixel) 早期的iPhone3GS的屏幕分辨率是320*480(PPI=163)iOS绘制图形(CGPoint/CGSize/CGRect)均以point为单位:1 point = 1 pixel 后来在iPhone4中,同样大小3.5 inch的屏幕采用了Retina显示技术,横、纵向方向像素密度都被放大到2倍,像素分辨率提高到(320x2)x(480x2)= 960x640(PPI=326)显像分辨率提升至iPhone3GS4倍1个Point被渲染成1个2x2的像素矩阵) 但是对于开发者来说,iOS绘制图形的API依然沿袭point为单位。在同样的逻辑坐标系下:1 point = scale*pixel(在iPhone4~6中,缩放因子scale=2;在iPhone6+中,缩放因子scale=3

  3. iPhone 各种机型尺寸信息列表入下表:

机型尺寸逻辑缩放因子(UIKit Scale factor)实际缩放因子(Native Scale factor)屏幕宽高(开发尺寸)屏幕分辨率是否全面屏有无刘海
3GS3.5寸1.01.0320x480320x480非全面屏
4(S)3.5寸2.02.0320x480640x960非全面屏
5(C)/5(S)/SE4寸2.02.0320x568640x1136非全面屏
6(S)/7/84.7寸2.02.0375x667750x1334非全面屏
6(S)+/7+/8+5.5寸3.02.608414x7361080x1920非全面屏
X/XS5.8寸3.03.0375x8121125x2436全面屏
XR6.1寸2.02.0414×896828 x1792全面屏
XS Max6.5寸3.03.0414×8961242x2688全面屏
需要注意的地方是6(S)+/7+/8+的时候,实际的缩放因子并不等于逻辑上的缩放因子。所以,他的屏幕分辨率是1080x1920而不是1242x2208
上述数据,可以通过代码获取逻辑缩放因子、逻辑屏幕宽度;实际缩放/物理因子、实际/物理屏幕宽度:
//逻辑缩放因子
[UIScreen mainScreen].scale
//逻辑屏幕宽度
[UIScreen mainScreen].bounds
 
//实际/物理缩放因子
[UIScreen mainScreen].nativeScale
//实际/物理屏幕宽度
[UIScreen mainScreen].nativeBounds

4. 适配常用宏

//获得屏幕的宽高
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
//iPhoneX / iPhoneXS
#define  isIphoneX_XS     kScreenWidth == 375.f && kScreenHeight == 812.f ? YES : NO
//iPhoneXR / iPhoneXSMax
#define  isIphoneXR_XSMax    kScreenWidth == 414.f && kScreenHeight == 896.f ? YES : NO
//异性全面屏
#define   isFullScreen    isIphoneX_XS || isIphoneXR_XSMax

// Status bar height.
#define  StatusBarHeight     isFullScreen ? 44.f : 20.f

// Navigation bar height.
#define  NavigationBarHeight  44.f

// Tabbar height.
#define  TabbarHeight         isFullScreen ? (49.f+34.f) : 49.f

// Tabbar safe bottom margin.
#define  TabbarSafeBottomMargin         isFullScreen ? 34.f : 0.f

// Status bar & navigation bar height.
#define  StatusBarAndNavigationBarHeight  isFullScreen ? 88.f : 64.f

5. 获取安全区域

+ (CGRect)GetSafeAreaImpl{
    UIView *view = UIApplication.sharedApplication.windows.lastObject;
//    UIView *view = (UIView *)GetAppController().unityView;
    CGRect area = [self CustomComputeSafeArea:view];
    //    x = area.origin.x;
    //    y = area.origin.y;
    //    w = area.size.width;
    //    h = area.size.height;
    return area;
}

+ (CGRect)CustomComputeSafeArea:(UIView *)view{
    CGSize screenSize = view.bounds.size;
    CGRect screenRect = CGRectMake(0, 0, screenSize.width, screenSize.height);
    
    UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 0, 0);
    if (@available(iOS 11.0, *)) {
        insets = [view safeAreaInsets];
    }
    screenRect.origin.x = screenRect.origin.x + insets.left;
    screenRect.origin.y = screenRect.origin.y + insets.top;
//    screenRect.size.width -= insets.left + insets.right;
    screenRect.size.width = screenRect.size.width - (insets.left + insets.right);
    screenRect.size.height = screenRect.size.height - (insets.top + insets.bottom);
    // 乘以缩放因子,根据需求可以省略
    float scale = view.contentScaleFactor;
    screenRect.origin.x = screenRect.origin.x * scale;
    screenRect.origin.y = screenRect.origin.y * scale;
    screenRect.size.width = screenRect.size.width * scale;
    screenRect.size.height = screenRect.size.height * scale;
    return screenRect;
}

6. 启动图数据

  1. 有刘海机型安全区域,有无刘海机型开发尺寸对比图 刘海机型安全区域 刘海机型开发尺寸 非刘海机型开发尺寸