最全最准确获取iOS 状态栏、导航栏、TabBar高度
前言
最近在iPhone 12 系列機(jī)型上開(kāi)發(fā)項(xiàng)目時(shí),發(fā)現(xiàn)使用項(xiàng)目提供的獲取狀態(tài)欄、導(dǎo)航欄高度方法獲取到的高度是錯(cuò)誤的,隨后跟蹤排查最終解決這個(gè)問(wèn)題,所以自己想簡(jiǎn)單的總結(jié)一下問(wèn)題原因和解決辦法。
本文主要介紹問(wèn)題原因和解決辦法,最終提供一個(gè)能準(zhǔn)確獲取iPhone 狀態(tài)欄、導(dǎo)航欄、TabBar高度的方法。
問(wèn)題原因
出現(xiàn)問(wèn)題的原因是,我們大多開(kāi)發(fā)在使用獲取狀態(tài)欄、導(dǎo)航欄高度方法都是以下方法來(lái)獲取的:
// 狀態(tài)欄高度,iPhoneX 是判斷是否為劉海屏 #define StatusBar_Height (isIPhoneX ? 44.0f : 20.0f)在iOS 14系統(tǒng)以前,使用這種方法獲取是沒(méi)有問(wèn)題的,但是在之后,劉海屏的手機(jī)狀態(tài)欄高度就不在是統(tǒng)一的44px咯,根據(jù)下表我們看一看目前iOS 15系統(tǒng)上的各機(jī)型的狀態(tài)欄高度:
| iPhone XR/11 | 48px |
| iPhone X/11 Pro/ 11 Pro Max/12 mini | 44px |
| iPhone 12/12 Pro/Pro Max | 47px |
使用系統(tǒng)方法獲取狀態(tài)欄高度
可以看出使用上面方法已經(jīng)不在滿足我們的開(kāi)發(fā)需求了,于是我就想到使用系統(tǒng)提供的方法來(lái)獲取,通過(guò)?UIApplication?單例中的?statusBarFrame?屬性獲取狀態(tài)狀態(tài)欄改度:
[UIApplication sharedApplication].statusBarFrame.size.height;我發(fā)現(xiàn) iOS 13.0系統(tǒng) 之后,UIApplication?單例中的?statusBarFrame?屬性被廢棄了。不建議使用了,系統(tǒng)希望我們使用?UIStatusBarManager?類中的?statusBarFrame?來(lái)進(jìn)行獲取:
if (@available(iOS 13.0, *)) {NSSet *set = [UIApplication sharedApplication].connectedScenes;UIWindowScene *windowScene = [set anyObject];UIStatusBarManager *statusBarManager = windowScene.statusBarManager;return statusBarManager.statusBarFrame.size.height; }
代碼模塊
為了統(tǒng)一和方便快速獲取系統(tǒng)頂部和底部安全區(qū)、頂部狀態(tài)欄和導(dǎo)航欄、底部 tabBar,我將新建一個(gè)分類來(lái)實(shí)現(xiàn)這些方法,方便項(xiàng)目全局引用:
在?UIDevice+StateHeight.h?中,聲明各方法名稱:
@interface UIDevice ()/** 頂部安全區(qū)高度 **/ + (CGFloat)dev_safeDistanceTop;/** 底部安全區(qū)高度 **/ + (CGFloat)dev_safeDistanceBottom;/** 頂部狀態(tài)欄高度(包括安全區(qū)) **/ + (CGFloat)dev_statusBarHeight;/** 導(dǎo)航欄高度 **/ + (CGFloat)dev_navigationBarHeight;/** 狀態(tài)欄+導(dǎo)航欄的高度 **/ + (CGFloat)dev_navigationFullHeight;/** 底部導(dǎo)航欄高度 **/ + (CGFloat)dev_tabBarHeight;/** 底部導(dǎo)航欄高度(包括安全區(qū)) **/ + (CGFloat)dev_tabBarFullHeight;@end在?UIDevice+StateHeight.m?中實(shí)現(xiàn)各方法進(jìn)行。
#import "UIDevice+StateHeight.h"@implementation UIDevice ()// 頂部安全區(qū)高度 + (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; }// 底部安全區(qū)高度 + (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; }//頂部狀態(tài)欄高度(包括安全區(qū)) + (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;} }// 導(dǎo)航欄高度 + (CGFloat)dev_navigationBarHeight {return 44.0f; }// 狀態(tài)欄+導(dǎo)航欄的高度 + (CGFloat)dev_navigationFullHeight {return [UIDevice vg_statusBarHeight] + [UIDevice vg_navigationBarHeight]; }// 底部導(dǎo)航欄高度 + (CGFloat)dev_tabBarHeight {return 49.0f; }// 底部導(dǎo)航欄高度(包括安全區(qū)) + (CGFloat)dev_tabBarFullHeight {return [UIDevice vg_statusBarHeight] + [UIDevice vg_safeDistanceBottom]; }@end總結(jié)
以上是生活随笔為你收集整理的最全最准确获取iOS 状态栏、导航栏、TabBar高度的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 指令——流水线和吞吐率
- 下一篇: appium自动化绘制锁屏图案