运行项目发现顶部状态栏在,iphone12和iphone12mini上高度变了。
Xcode12.1以后
运行或者发布的项目必须适配iphone12系列的状态条高度,否则发布的新包会有显示问题。
一、以下是未隐藏状态条的测试
-
红色view
为安全区域
-
黑色view
的top为statusBarFrame.size.height
-
黄色view
的top为window.safeAreaInsets.top
- (void)viewDidLoad {
[super viewDidLoad];
UIStatusBarManager *statusBarManager = [UIApplication.sharedApplication.windows firstObject].windowScene.statusBarManager;
NSLog(@"%f,%f",UIApplication.sharedApplication.statusBarFrame.size.width,UIApplication.sharedApplication.statusBarFrame.size.height);
NSLog(@"%f,%f",statusBarManager.statusBarFrame.size.width,statusBarManager.statusBarFrame.size.height);
UIWindow *window = [UIApplication.sharedApplication.windows firstObject];
NSLog(@"top == %f",window.safeAreaInsets.top);
NSLog(@"bottom == %f",window.safeAreaInsets.bottom);
NSLog(@"getStatusBarHeight == %f",[[self class] getStatusBarHeightBySafeArea]);
NSLog(@"getBottomSafeHeight == %f",[[self class] getBottomSafeHeight]);
UIView *blackView = [[UIView alloc] init];
blackView.backgroundColor = [UIColor blackColor];
blackView.frame = CGRectMake(0, statusBarManager.statusBarFrame.size.height, 100, 200);
[self.view addSubview:blackView];
UIView *yellowView = [[UIView alloc] init];
yellowView.backgroundColor = [UIColor yellowColor];
yellowView.frame = CGRectMake(CGRectGetMaxX(blackView.frame), [[self class] getStatusBarHeightBySafeArea], 100, 200);
[self.view addSubview:yellowView];
}
+ (CGFloat)getStatusBarHeightBySafeArea {
if (@available(iOS 11.0, *)) {
// 非刘海屏,若存在状态条隐藏显示的切换,会有window.safeAreaInsets.top返回为0的异常情况
if ([self.class screenIsBangs]) {
UIWindow *window = [UIApplication.sharedApplication.windows firstObject];
return window.safeAreaInsets.top;
}
}
return 20;
}
+ (CGFloat)getBottomSafeHeight {
if (@available(iOS 11.0, *)) {
UIWindow *window = [UIApplication.sharedApplication.windows firstObject];
return window.safeAreaInsets.bottom;
}
return 0;
}
+ (BOOL)screenIsBangs {
if (@available(iOS 11.0, *)) {
UIWindow *window = [UIApplication.sharedApplication.windows firstObject];
return (window.safeAreaInsets.bottom > 0);
}
return NO;
}
终端输出:
2020-11-11 11:28:45.454855+0800 14demo[58780:1454552] 375.000000,44.000000
2020-11-11 11:28:45.455105+0800 14demo[58780:1454552] 375.000000,44.000000
2020-11-11 11:28:45.455526+0800 14demo[58780:1454552] top == 50.000000
2020-11-11 11:28:45.455783+0800 14demo[58780:1454552] bottom == 34.000000
2020-11-11 11:28:45.456136+0800 14demo[58780:1454552] getStatusBarHeight == 50.000000
2020-11-11 11:28:45.456353+0800 14demo[58780:1454552] getBottomSafeHeight == 34.000000
以下为高度:
-
iphone12、iphone12pro、iphone12proMax
statusBarFrame
获取高度为47,safeAreaInsets.top
的高度为47 -
iphone12mini
statusBarFrame
获取高度为44,safeAreaInsets.top
的高度为50
二、以下是隐藏状态条的测试
终端输出:
2020-11-11 11:32:25.391062+0800 14demo[58845:1459790] 0.000000,0.000000
2020-11-11 11:32:25.391364+0800 14demo[58845:1459790] 0.000000,0.000000
2020-11-11 11:32:25.391849+0800 14demo[58845:1459790] top == 50.000000
2020-11-11 11:32:25.392080+0800 14demo[58845:1459790] bottom == 34.000000
2020-11-11 11:32:25.392341+0800 14demo[58845:1459790] getStatusBarHeight == 50.000000
2020-11-11 11:32:25.392557+0800 14demo[58845:1459790] getBottomSafeHeight == 34.000000
以下为高度:
-
iphone12、iphone12pro、iphone12proMax
statusBarFrame
获取高度为0,safeAreaInsets.top
的高度为47 -
iphone12mini
statusBarFrame
获取高度为0,safeAreaInsets.top
的高度为50
总结
根据上边的情况,建议获取状态条高度通过window.safeAreaInsets.top
来获取。
这种在项目中需要定值写死的状态值,不建议通过statusBarFrame.size.height
来获取高度。