iOS - iPhone手机刘海屏判断

news/2024/10/16 16:46:35/

2022.04.11 更新,修改获取 iPhone 状态栏、导航栏、TabBar高度等部分内容。


前言

最近写毕业设计的时候,发现 iPhoneX 之后的刘海屏手机顶部状态栏高度底部TabBar高度和原来不一样了,这就需要我们对刘海屏手机做单独的 UI 布局适配了。

刘海屏判断

适配的核心是要对刘海屏进行判断,以下针对刘海屏手机的特征,提供了两种判断方法。

1. 安全区底部边距判断法

在 iOS 11 之后,多了安全区(下图蓝色区域)的概念。刘海屏手机因为多了下方的小黑条,底部安全区存在距离屏幕底部的边距,而且这是非刘海屏所不具有的
safe_area
因此,我们可以将其作为判断刘海屏的依据。如果系统大于 iOS 11 且安全区底部到屏幕底部存在间距,就将其判断为刘海屏。代码如下:

// 刘海屏判断
#define iPhoneX ({ \BOOL iPhoneX = NO; \if (@available(iOS 11.0, *)) { \if ([UIApplication sharedApplication].windows[0].safeAreaInsets.bottom > 0) { \iPhoneX = YES; \} \} \iPhoneX; \
})

2. 屏幕宽高比判断法

考虑到我不太喜欢写这种多行宏定义,据说会降低编译速度。我又继续寻找其他刘海屏的特征,终于在下面这一张图中找到了灵感。
在这里插入图片描述
由上图所示,但凡是刘海屏手机,屏幕的纵横比都是 19 : 9

设手机屏幕宽度为 W i d t h Width Width,高度为 H e i g h t Height Height。根据屏幕纵横比规律,它只要满足以下两个条件其中一个,我们就能判它是刘海屏。
∣ H e i g h t W i d t h − 812 375 ∣ < 0.01 |\frac{Height}{Width} - \frac{812}{375}| < 0.01 WidthHeight375812<0.01

∣ H e i g h t W i d t h − 896 414 ∣ < 0.01 |\frac{Height}{Width} - \frac{896}{414}| < 0.01 WidthHeight414896<0.01

代码如下:

// 刘海屏判断
#define iPhoneX (ABS(MAX(CGRectGetWidth([UIScreen mainScreen].bounds), CGRectGetHeight([UIScreen mainScreen].bounds)) / MIN(CGRectGetWidth([UIScreen mainScreen].bounds), CGRectGetHeight([UIScreen mainScreen].bounds)) - 896 / 414.0) < 0.01 || ABS(MAX(CGRectGetWidth([UIScreen mainScreen].bounds), CGRectGetHeight([UIScreen mainScreen].bounds)) / MIN(CGRectGetWidth([UIScreen mainScreen].bounds), CGRectGetHeight([UIScreen mainScreen].bounds)) - 812 / 375.0) < 0.01)

PS:用小于 0.01 是为了避免精度问题,以及 iPhone 12 系列和前面刘海屏手机的纵横比存在一定误差。

相关常用宏 (deprecated ⚠️ )

既然有了刘海屏的判断, 后面的工作就变得简单起来了。下面是我在编写相关代码的时候所写的宏,有需要的同学可以参考一下。

// 屏幕宽度
#define ScreenWidth [UIScreen mainScreen].bounds.size.width// 屏幕高度
#define ScreenHeight [UIScreen mainScreen].bounds.size.height// 状态栏高度 (deprecated)
#define StatusBar_Height (iPhoneX ? 44.0f : 20.0f)// 导航栏高度 (deprecated)
#define NaviBar_Height (44.0f)// 状态栏+导航栏高度 (deprecated)
#define StatusBar_NaviBar_Height (StatusBar_Height + NaviBar_Height)// TabBar高度 (deprecated)
#define TabBar_Height (iPhoneX ? 49.0f + 34.0f : 49.0f)

以上内容已经不能成为通用的方法了,如果依旧有需要的话,可以看一篇「iOS 准确获取 iPhone 状态栏、导航栏、TabBar高度,看这篇就够了」。

参考资料

  • 官方文档:Adaptivity and Layout
  • https://www.jianshu.com/p/392489853d92
  • https://www.strerr.com/screen.html

http://www.ppmy.cn/news/682434.html

相关文章

uni-app刘海屏处理

前提&#xff1a;本次主要是解决刘海屏的问题&#xff0c;比如下面这种&#xff1a; 1、在main.js封装一个函数&#xff08;全局封装&#xff0c;这样子就可以在任意页面用this调用该函数&#xff09; Vue.prototype.getPhoneInfo function(){const phoneInfo uni.getSyste…

判断刘海屏

/*** 判断是否是刘海屏* return*/ public static boolean hasNotchScreen(Activity activity){if (getInt("ro.miui.notch",activity) 1 || hasNotchAtHuawei(activity) || hasNotchAtOPPO(activity)|| hasNotchAtVivo(activity) || isAndroidP(activity)){ //TODO …

沉浸式,状态栏高度,刘海屏怎么开启,适配

沉浸式&#xff0c;状态栏高度&#xff0c;刘海屏怎么开启&#xff0c;怎么适配&#xff1f;看这&#xff01; 何为沉浸式&#xff1f; 沉浸式就是app的头部和状态栏和何为一体的&#xff0c;webview即为整个手机的高度 何为状态栏&#xff1f; 状态栏就是手机顶部&#xff…

刘海屏判断

判断vivo是否有刘海屏 /*** 判断vivo是否有刘海屏* https://swsdl.vivo.com.cn/appstore/developer/uploadfile/20180328/20180328152252602.pdf* return*/private static boolean hasNotchVIVO() {try {Class<?> c Class.forName("android.util.FtFeature"…

入手评测 联想小新pro16参数配置

联想小新Pro 16配备16英寸窄边框雾面屏&#xff0c;分辨率2560x1600&#xff0c;16:10黄金比例&#xff0c;刷新率最高可选120Hz。350nits高亮度、100% sRGB高色域、莱茵硬件低蓝光Eyesafe认证、DC调光无频闪。 联想小新pro16新品活动 爆降600这活动太给力了 机会不容错过http:…

前端iPhone刘海屏适配

对于iPhone系列出的越来越多&#xff0c;如果只是使用media来做适配的话&#xff0c;老代码想要适配新机型还是有一定局限性的。 今天去搜了搜相关的解决方法&#xff0c;那么就来总结一下。 安全区 早期苹果对于 iPhone X 的设计布局意见如下&#xff1a; 核心内容应该处于 …

镜面屏与雾面屏

●阅前扫盲&#xff1a;什么是镜面屏和雾面屏&#xff1f; 雾面屏&#xff1a;表面粗糙、摸上去带有磨砂质感的液晶显示屏。这类显示屏的表面经过防眩光处理&#xff0c;整体画质像蒙上了一层薄薄的雾&#xff0c;不会刺眼&#xff0c;但透光性有所缩减。液晶发展初期比较流行&…

Kubernetes删除ns(namespace)

一、前言 删除某个应用或模块的时候&#xff0c;可能会出现命名空间的状态一直处于Terminating状态&#xff0c;无论是重启k8s还是重启所有服务器都没卵用。 k8s遇到有无法删除的ns&#xff08;namespace&#xff09;命名空间的时候&#xff0c;可以尝试几种删除方式 二、删…