先来认识
px
与pt
区别px
就是表示pixel
像素,是屏幕上显示数据的最基本的点,它不是自然界的长度单位,点的大小是会变的,也称为相对长度
;pt
就是point
,是印刷行业常用单位磅
,等于1/72英寸,所以它是一个自然界标准的长度单位,也称为绝对长度
。我们再来了解缩放因子
(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)
显像分辨率提升至iPhone3GS
的4倍
(1个Point
被渲染成1个2x2的像素矩阵
)
但是对于开发者来说,iOS
绘制图形的API
依然沿袭point
为单位。在同样的逻辑坐标系下:1 point = scale*pixel
(在iPhone4~6
中,缩放因子scale=2
;在iPhone6+
中,缩放因子scale=3
)iPhone 各种机型尺寸信息列表入下表:
机型 | 尺寸 | 逻辑缩放因子(UIKit Scale factor) | 实际缩放因子(Native Scale factor) | 屏幕宽高(开发尺寸) | 屏幕分辨率 | 是否全面屏 | 有无刘海 |
---|---|---|---|---|---|---|---|
3GS | 3.5寸 | 1.0 | 1.0 | 320x480 | 320x480 | 非全面屏 | 无 |
4(S) | 3.5寸 | 2.0 | 2.0 | 320x480 | 640x960 | 非全面屏 | 无 |
5(C)/5(S)/SE | 4寸 | 2.0 | 2.0 | 320x568 | 640x1136 | 非全面屏 | 无 |
6(S)/7/8 | 4.7寸 | 2.0 | 2.0 | 375x667 | 750x1334 | 非全面屏 | 无 |
6(S)+/7+/8+ | 5.5寸 | 3.0 | 2.608 | 414x736 | 1080x1920 | 非全面屏 | 无 |
X/XS | 5.8寸 | 3.0 | 3.0 | 375x812 | 1125x2436 | 全面屏 | 有 |
XR | 6.1寸 | 2.0 | 2.0 | 414×896 | 828 x1792 | 全面屏 | 有 |
XS Max | 6.5寸 | 3.0 | 3.0 | 414×896 | 1242x2688 | 全面屏 | 有 |
需要注意的地方是6(S)+/7+/8+
的时候,实际的缩放因子并不等于
逻辑上的缩放因子。所以,他的屏幕分辨率是1080x1920
而不是1242x2208
上述数据,可以通过代码获取逻辑缩放因子、逻辑屏幕宽度;实际缩放/物理因子、实际/物理屏幕宽度:1
2
3
4
5
6
7
8
9//逻辑缩放因子
[UIScreen mainScreen].scale
//逻辑屏幕宽度
[UIScreen mainScreen].bounds
//实际/物理缩放因子
[UIScreen mainScreen].nativeScale
//实际/物理屏幕宽度
[UIScreen mainScreen].nativeBounds
- 适配常用宏
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24//获得屏幕的宽高
#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 - 获取安全区域
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32+ (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;
} 启动图数据
有刘海机型安全区域,有无刘海机型开发尺寸对比图