iOS14 StatusBar高度获取方法失效

运行项目发现顶部状态栏在,iphone12和iphone12mini上高度变了。
Xcode12.1以后运行或者发布的项目必须适配iphone12系列的状态条高度,否则发布的新包会有显示问题。

一、以下是未隐藏状态条的测试

  • 红色view安全区域
  • 黑色view的top为statusBarFrame.size.height
  • 黄色view的top为window.safeAreaInsets.top
    image.png
- (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

以下为高度:

  1. iphone12、iphone12pro、iphone12proMax
    statusBarFrame获取高度为47,safeAreaInsets.top的高度为47
  2. iphone12mini
    statusBarFrame获取高度为44,safeAreaInsets.top的高度为50

二、以下是隐藏状态条的测试

image.png

终端输出:

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

以下为高度:

  1. iphone12、iphone12pro、iphone12proMax
    statusBarFrame获取高度为0,safeAreaInsets.top的高度为47
  2. iphone12mini
    statusBarFrame获取高度为0,safeAreaInsets.top的高度为50

总结

根据上边的情况,建议获取状态条高度通过window.safeAreaInsets.top来获取
这种在项目中需要定值写死的状态值,不建议通过statusBarFrame.size.height来获取高度。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容