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

这篇具有很好参考价值的文章主要介绍了最全最准确获取iOS 状态栏、导航栏、TabBar高度。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

最近在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 中实现各方法进行。文章来源地址https://www.toymoban.com/news/detail-442292.html

#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高度的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包