前言

最近在iPhone 12 系列机型上开发项目时,发现使用项目提供的获取状态栏、导航栏高度方法获取到的高度是错误的,随后跟踪排查最终解决这个问题,所以自己想简单的总结一下问题原因和解决办法。

本文主要介绍问题原因和解决办法,最终提供一个能准确获取iPhone 状态栏、导航栏、TabBar高度的方法。

问题原因

出现问题的原因是,我们大多开发在使用获取状态栏、导航栏高度方法都是以下方法来获取的:

// 状态栏高度,iPhoneX 是判断是否为刘海屏
#define StatusBar_Height (isIPhoneX ? 44.0f : 20.0f)

在iOS 14系统以前,使用这种方法获取是没有问题的,但是在之后,刘海屏的手机状态栏高度就不在是统一的44px咯,根据下表我们看一看目前iOS 15系统上的各机型的状态栏高度:

机型 状态栏高度
iPhone XR/11 48px
iPhone X/11 Pro/ 11 Pro Max/12 mini 44px
iPhone 12/12 Pro/Pro Max 47px

使用系统方法获取状态栏高度

可以看出使用上面方法已经不在满足我们的开发需求了,于是我就想到使用系统提供的方法来获取,通过 UIApplication 单例中的 statusBarFrame 属性获取状态状态栏改度:

[UIApplication sharedApplication].statusBarFrame.size.height;

我发现 iOS 13.0系统 之后,UIApplication 单例中的 statusBarFrame 属性被废弃了。不建议使用了,系统希望我们使用 UIStatusBarManager 类中的 statusBarFrame 来进行获取:

if (@available(iOS 13.0, *)) {NSSet *set = [UIApplication sharedApplication].connectedScenes;UIWindowScene *windowScene = [set anyObject];UIStatusBarManager *statusBarManager = windowScene.statusBarManager;return statusBarManager.statusBarFrame.size.height;
}

代码模块

为了统一和方便快速获取系统顶部和底部安全区、顶部状态栏和导航栏、底部 tabBar,我将新建一个分类来实现这些方法,方便项目全局引用:

在 UIDevice+StateHeight.h 中,声明各方法名称:

@interface UIDevice ()/** 顶部安全区高度 **/
+ (CGFloat)dev_safeDistanceTop;/** 底部安全区高度 **/
+ (CGFloat)dev_safeDistanceBottom;/** 顶部状态栏高度(包括安全区) **/
+ (CGFloat)dev_statusBarHeight;/** 导航栏高度 **/
+ (CGFloat)dev_navigationBarHeight;/** 状态栏+导航栏的高度 **/
+ (CGFloat)dev_navigationFullHeight;/** 底部导航栏高度 **/
+ (CGFloat)dev_tabBarHeight;/** 底部导航栏高度(包括安全区) **/
+ (CGFloat)dev_tabBarFullHeight;@end

在 UIDevice+StateHeight.m 中实现各方法进行。

#import "UIDevice+StateHeight.h"@implementation UIDevice ()// 顶部安全区高度
+ (CGFloat)dev_safeDistanceTop {if (@available(iOS 13.0, *)) {NSSet *set = [UIApplication sharedApplication].connectedScenes;UIWindowScene *windowScene = [set anyObject];UIWindow *window = windowScene.windows.firstObject;return window.safeAreaInsets.top;} else if (@available(iOS 11.0, *)) {UIWindow *window = [UIApplication sharedApplication].windows.firstObject;return window.safeAreaInsets.top;}return 0;
}// 底部安全区高度
+ (CGFloat)dev_safeDistanceBottom {if (@available(iOS 13.0, *)) {NSSet *set = [UIApplication sharedApplication].connectedScenes;UIWindowScene *windowScene = [set anyObject];UIWindow *window = windowScene.windows.firstObject;return window.safeAreaInsets.bottom;} else if (@available(iOS 11.0, *)) {UIWindow *window = [UIApplication sharedApplication].windows.firstObject;return window.safeAreaInsets.bottom;}return 0;
}//顶部状态栏高度(包括安全区)
+ (CGFloat)dev_statusBarHeight {if (@available(iOS 13.0, *)) {NSSet *set = [UIApplication sharedApplication].connectedScenes;UIWindowScene *windowScene = [set anyObject];UIStatusBarManager *statusBarManager = windowScene.statusBarManager;return statusBarManager.statusBarFrame.size.height;} else {return [UIApplication sharedApplication].statusBarFrame.size.height;}
}// 导航栏高度
+ (CGFloat)dev_navigationBarHeight {return 44.0f;
}// 状态栏+导航栏的高度
+ (CGFloat)dev_navigationFullHeight {return [UIDevice vg_statusBarHeight] + [UIDevice vg_navigationBarHeight];
}// 底部导航栏高度
+ (CGFloat)dev_tabBarHeight {return 49.0f;
}// 底部导航栏高度(包括安全区)
+ (CGFloat)dev_tabBarFullHeight {return [UIDevice vg_statusBarHeight] + [UIDevice vg_safeDistanceBottom];
}@end

最全最准确获取iOS 状态栏、导航栏、TabBar高度相关推荐

  1. iOS 准确获取 iPhone 状态栏、导航栏、TabBar高度,看这篇就够了

    前言 最近在项目开发的时候,发现项目提供的获取 「状态栏+导航栏高度」的方法,在 iPhone 12 系列机型上是错误的.解决了这个问题之后,决定做个简单的总结,于是有了这篇文章. 本文主要是分析了遇 ...

  2. iOS 解决导航栏pop返回时出现黑块问题!

    iOS 解决导航栏pop返回时出现黑块问题! 问题描述: 导航栏正常从A页面push到B页面,从B页面pop返回A页面时遇到过渡过程中导航栏出现黑块的问题. 如截图所示: 问题原因: A界面导航栏被影 ...

  3. IOS设置导航栏返回按钮,并添加事件返回主页面

    IOS设置导航栏返回按钮,并添加事件返回主页面 前提是已经push了一个viewController了.才能使用. XXXTableViewController 里面书写 - (void)viewDi ...

  4. IOS设置导航栏的背景图片和文字

    IOS设置导航栏的背景图片和文字 - (void)viewDidLoad {[super viewDidLoad];[self.navigationBar setBackgroundImage:[UI ...

  5. ios 添加导航栏视图_iOS进度栏(进度视图)

    ios 添加导航栏视图 In this tutorial, we'll be discussing the UIProgressView component and create a progress ...

  6. 成品app直播源码,全屏并且去掉底部虚拟导航栏

    成品app直播源码,全屏并且去掉底部虚拟导航栏 @Overridepublic void onWindowFocusChanged(boolean hasFocus) {super.onWindowF ...

  7. MUI-设置沉浸式状态栏后MUI导航栏的高度问题

    上篇文章实现了沉浸式状态栏,如果不使用MUI的导航栏可以不用关心这个问题.由于我们的项目一开始被大量使用了MUI的导航栏,所以决定解决这个问题,不然就要对项目做大量的修改,时间成本太高. 问题描述与分 ...

  8. uni-app小程序onShow执行两次;微信小程序onShow重复执行原因;导航栏tabBar页的onLoad函数不执行;App.vue页的onShow执行原因;onShow莫名其妙执行

    1.只有五种情况会触发导航栏tabBar页的onLoad函数,分别是: –1.1:首次进入到导航栏tabBar页面: –1.2:从微信分享进入的导航栏tabBar页面: –1.3:识别二维码跳转到小程 ...

  9. 小程序 底部导航栏(tabBar)图标的正确做法

    许多人都认为小程序系统的底部导航栏特别不好看,为了美观而选择自定义,从此身陷漩涡无法自拔.其实真正的原因是图标的图片处理不当(说白了就是前端和设计太菜了),导致会有线条变粗,间距不当的视觉感受. 除小 ...

最新文章

  1. AI 监视打工人,这个国家明确说:保护我方“摸鱼权”!
  2. Genymotion配置及使用教程(最新最完整版附各部分下载地址)最快模拟器
  3. 完全禁用Microsoft Compatibility Telemetry
  4. iOS开发总结(A0)- MultipeerConnectivity
  5. 一段可自动点击运行代码(只偷偷的点一次)
  6. oracle ^]字符,oracle数据中特殊字符处理
  7. Windows 多个系统版本惊现大漏洞,攻击者可随意操作程序!
  8. 模块化分析设计(简单的注册登录模块)
  9. 如何在Inceptor中使用日期函数获取与转换时间
  10. 网站建设php的心得和体会,网页设计心得体会
  11. SPSS基本数据处理(二)
  12. bugku-pokergame
  13. 批量图片处理:如何给多个图片都加上连续的序号?
  14. 模拟电路 二极管伏安特性(一)
  15. u盘盘符不显示 win10_Win10不显示U盘的盘符怎么办丨Win10不显示U盘的盘符解决方法...
  16. 视频文件服务器加速,百度云加速视频加速缓存设置教学
  17. 11_JavaWeb三大组件之Filter拦截器与Listener监听器
  18. 大学生找工作如何做自我介绍?如何做好自我介绍?
  19. 交叉编译openssl(arm和x86_64)
  20. 采访了“996背后的那些人”:孤立无援,进退两难

热门文章

  1. 深圳实验室设计合理化事项
  2. JAVA获取请求头header中的参数
  3. 安卓生成word文档(使用了Spire.Doc.Android)
  4. PHP应该学什么,如何学好PHP(一)
  5. 全功能版SEO动态寄生虫-15项功能霸屏排名版
  6. # 联邦学习-安全树模型 SecureBoost之集成学习
  7. 手机计算机上输入错误是什么意思,电脑输入验证码总是提示错误该怎么解决?...
  8. 计算机CPU后面09B啥意思,电脑启动出现CPU FAN ERROR 解决方法【方法详解】
  9. 服务器地址 端口 协议 密码,服务器地址和端口及密码
  10. springCloud 初探