你的旧版本 App 为何运行在 iPhone 12 上没有异常?
背景
当我在 10月14日 iPhone 12 系列发布直播,看到 iPhone 12 系列的分辨率后,我注意到这些分辨率是全新的时,我立即在群里吐槽:又需要适配一波了。我只是以为宽高变化会导致字号变化,然而更严重的问题是我们判断是否是刘海屏使用了如下代码(这种写法是不完善的);
self.is_iphonex = (SCREEN_MAX_LENGTH812.f || SCREEN_MAX_LENGTH896.f);
是否是刘海屏是枚举所有符合预期的设备高度来判断的,它的好处是快速稳定,但遇到新机型就悲催了。在新 iPhone 12 系列中,屏幕高度分别为:
Device Retina 屏幕像素 (pt) 物理像素 (px)
iPhone 12 Pro 6.7″ 3X 926 x 428 2778 x 1284
iPhone 12 Pro 6.1″ 3X 390 x 844 2532 x 1170
iPhone 12 6.1″ 3X 390 x 844 2532 x 1170
iPhone 12 Mini 5.4″ 3X 360 x 780 2340 x 1080
iPhone 11 Pro Max 3X 414 x 896 2688 x 1242
所以如果(SCREEN_MAX_LENGTH812.f || SCREEN_MAX_LENGTH896.f) 代码来判断刘海屏,定位导航栏位置肯定是错误的。预期表现是导航栏被刘海遮住。
巡查App Store 的 App 在 iPhone 12 的表现
当我拿到 蓝色 iPhone 12 的第一件时间就是看看各个 App 在适配方便有哪些异常表现,大概看了10 几个 App,除了 斗鱼,哔哩哔哩 外大部分适配都没有大问题。有问题,我不意外,
斗鱼顶部导航适配出错
,但是其他 App ,包括我们自己的 App,全屏的界面导航都没问题。
严选 App
为什么有些 OK,有些异常?
经过实际测试,分别用 Xcode 12.0 和 Xcode 12.1 分别在真机 iPhone 12 上运行;发现 Xcode 12.1 build 的 App 真机运行是有问题的。所有目前 App Store 里运行有问题的 App,如斗鱼,是用了 Xcode 12.1 最新版本上传的 ipa。所以他们的差别在哪里?
观察到, Xcode 12.1 里已经有 iPhone 12 的模拟器,所以说用 Xcode 12.1 是认识 iPhone 12 的。回想几年前当 iPhone X 出现时,旧的 App 是如何在 iPhone X 上表现的—— App 运行在屏幕的中间,上线留有黑边。
这里需要解释下苹果 App 的向后兼容规则:
当 App 运行在自己不认识的新设备上时,系统会把新设备当做上一代的设备来使用。换言之,新设备运行 的App 在兼容模式。避免 App 去处理 build 之时,还不存在的设备上。
这个规则在用户在设置 -> 显示和亮度 -> 放大显示 里设置了放大效果时,就是如此兼容的。
iPhone 11 Pro Max 标准显示(Standard Zoom) 下分辨率是 414×896 points;而如果设置为放大显示(Display Zoom)会被当做 iPhone 11 Pro 设备,此时分辨率是 375×812 points。
运作在兼容模式,一些常见的高度,如 statusbar、 bottombar 的尺寸是有影响的。
真实 iPhone 11 Pro 的顶部安全距离是 44,底部安全距离是 34;而运行在放大显示(Display Zoom)下,虽然屏幕分辨率相同,但顶部安全距离是 40,底部安全距离是 31;
结论
因为用 Xcode 12.0 打的 ipa,在 iPhone 12 上运行在兼容模式,尺寸是 iPhone 11,重点是顶部安全距离、底部安全距离都合 iPhone 11 保持一致,所以不会有问题;而用 Xcode 12.1 打的包,运行在了全新的分辨率,如果没有适配,肯定出问题。
附录, 正确判断是否是刘海屏的方法
苹果会推荐我们使用 safeAreaInsets 来获取,从 ViewController.view 获取时,时机太迟了,需要从更早创建的地方获取如 keyWindow,如:
(CGFloat)topOffset{
if (@available(iOS 11, *)) {
return [UIApplication sharedApplication].keyWindow.safeAreaInsets.top + kNavigationbarHeight;
}return 20 + kNavigationbarHeight;
}
直接使用 topOffset 来设置顶部安全距离或者通过判断 bottomOffset 是否大于 0 来确认是否是刘海屏,进而设置不同尺寸。
如果是判断刘海屏然后再加 statusbar 高度的作法(不推荐),你还需要完整的 statusbar 高度的表;
iPhone11: 48
iPhone12/12 pro/12 pro max: 47
iPhone12 mini: 50 (工作在 iPhone 11 Pro 缩放模式)
iPad Pro、IPad Air: 24
Other iPhones: 44.
非刘海屏: 20
参考
How iOS Apps Adapt to the various iPhone 12 Screen Sizes
WWDC 2019: 224 Modernizing Your UI for iOS 13
你的旧版本 App 为何运行在 iPhone 12 上没有异常?的更多相关文章
- 旧版本APP被开发人员下架,新版本重新上传依然显示被下架
新接了一个项目,这个项目在苹果商城上面的版本已经被原来另外一家公司的开发人员下架.我们重新设计.开发.上传,申请加急审核,终于完成手动发布.但是发布成功后,新版本提示:被开发人员下架.以前虽然迭代开发 ...
- IOS如何下载旧版本应用APP
前言 文章相对来说比较复杂,特别是查找版本ID对应的步骤,这里推荐使用另一种方案,操作起来更简单. 本文介绍如何使用Workflow及Fiddler下载IOS旧版本APP应用. 实现原理 通过Work ...
- 下载历史版本App超详细教程
有些时候我们需要下载旧版本的 App 进行研究或者其他用途,然而在 iOS 下,苹果的 App Store 里面默认只能下载最新版本的 App,对滴,就是这么任性,不服不行.然而在 Android 里 ...
- 下载历史版本App
文/timhbw(简书作者)原文链接:http://www.jianshu.com/p/edfed1b1822c著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 1.软件准备 [必备]C ...
- 青花瓷运用->下载历史版本App
1.软件准备 [必备]Charles4.0.1 下载密码: jfnk [不需要,配合Charles食用效果更佳]Paw2.3.1 下载密码: t3my 2.正式开始 2.1 打开Charles青花瓷 ...
- 混合式App开发 Apicloud 官方iPhone X 适配
iPhone X 适配 由于iPhone X的特殊造型,为了方便开发者对iPhone X进行适配,苹果在iOS 11中引入了Safe Area的概念,引擎也在api对象下添加了safeArea属性和s ...
- 利用 Charles Proxy 下载旧版本 iOS App
一.软件准备 1.旧版本 iTunes1.IPSW Downloads:https://ipsw.me/2.百度网盘链接: https://pan.baidu.com/s/1PO9Z12o-rqZ_J ...
- python3.7环境下创建app,运行Django1.11版本项目报错SyntaxError: Generator expression must be parenthesized
咳咳!!! 今天用命令行创建django项目中的app应用,出现了这样一个错误 这个错误在python3.6版本下安装运行django 1.11版本正常运行,但python3.7版本下运行django ...
- python3.7环境下创建app、运行Django1.11版本项目报错Generator expression must be parenthesized
有些同学喜欢追求新鲜感~但追求新鲜感终归是要付出一点点代价的 在编程领域有一句至理名言:用东西不要用最新的! 就像每次苹果系统的升级都会有相当一部分用户的手机成砖一样 下面我们就介绍一个因版本升级带来 ...
随机推荐
- Docker开启远程连接,本地IDEA使用docker插件连接(不认证的版本和认证的版本都有)
前言 在学校学习的时候,要部署一个Java程序,一般是打成war包,放到服务器上的tomcat的webapp里面去: 后来SpringBoot出现内置了tomcat,就直接打成jar包,丢到服务器任何 ...
- 2020 CSP-J 初赛答案及解析
部分咕咕咕的明天一定 单项选择 A A D 解析 : 与z的都是假 C 解析 : $ \frac{2048\times1024\times32}{8\times1024\times1024}=8$ C ...
- Termux基础教程(二):软件包安装
Termux基础教程(二):软件包安装 Termux是一个在安卓手机上模拟Linux系统的高级终端,这个终端十分强大,实用. Termux可以安装Liunx的各种软件包,这就是Termux的灵魂所在. ...
- 【C语言教程】“双向循环链表”学习总结和C语言代码实现!
双向循环链表 定义 双向循环链表和它名字的表意一样,就是把双向链表的两头连接,使其成为了一个环状链表.只需要将表中最后一个节点的next指针指向头节点,头节点的prior指针指向尾节点,链表就能成环儿 ...
- 【C语言编程入门笔记】排序算法之快速排序,一文轻松掌握快排!
排序算法一直是c语言重点,各个算法适应不用的环境,同时,在面试时,排序算法也是经常被问到的.今天我们介绍下快速排序,简称就是快排. 1.快速排序思想: 快排使用 分治法 (Divide and con ...
- mysql锁 转
参考文章:https://blog.csdn.net/puhaiyang/article/details/72284702 一.mysql锁的结构图 如上图所示,针对mysql的innodb存储引擎, ...
- js 实现 input file 文件上传
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat=&qu ...
- List<String>转换为实体类的属性【转】
package model; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arr ...
- drf Serializer使用
drf序列化 在前后端不分离的项目中,可以使用Django自带的forms组件进行数据验证,也可以使用Django自带的序列化组件对模型表数据进行序列化. 那么在前后端分离的项目中,drf也提供了数据 ...
- Tomcat8升级后URL中特殊字符报错出现原因
请求带上花括号等字符,请求无法送达服务端,报错: Failed to load resource: the server responded with a status of 400 () https ...