你的旧版本 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
有些同学喜欢追求新鲜感~但追求新鲜感终归是要付出一点点代价的 在编程领域有一句至理名言:用东西不要用最新的! 就像每次苹果系统的升级都会有相当一部分用户的手机成砖一样 下面我们就介绍一个因版本升级带来 ...
随机推荐
- RHSA-2017:2930-重要: 内核 安全和BUG修复更新(需要重启、存在EXP、本地提权、代码执行)
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...
- mac电脑上安装appium报错:Failed at the appium-chromedriver@4.25.1 postinstall script.
mac电脑安装appium,装好node.js后,使用命令:npm install appium@1.18.0,安装appium,报如下错误 ``` ERR! errno1 ERR! appium-c ...
- lua 1.0 源码分析 -- 1 lua 的虚拟指令
lua的解释器拿到 lua 编写的源码,首先进行解析,就是进行词法分析和语法分析,将源码转换成 lua 的指令集,然后执行这个指令集. lua 源码: function f(val) return v ...
- CSGO 服务端扩展插件开发记录之"DropClientReason"(1)
最近开始接触到了CSGO这款游戏,还是老套路,就是想千方百计的从里面增添新的游戏功能,当然刚开始想做到游刃有余是有点困难, 跟之前做CS1.6的第三方开发一样,都得自己慢慢的摸索过来,纵然CSGO所使 ...
- CSS语法规范与代码风格
CSS语法规范与代码风格 1. 语法规范 CSS规则又两个主要的部分构成:选择器+一条或多条声明. 选择器:用于指定CSS样式的HTML标签,花括号内的是设置的具体样式 属性与属性值以键值对的形式出现 ...
- 多测师讲解自动化 _邮件发送_高级讲师肖sir
第一步.进入如下网址申请163邮箱. https://mail.163.com/ 第二步.注册完之后登录.点击如下图设置点击POP3/SMTP/IMAP. 第三步.右侧点击客户端授权密码. 第四步. ...
- JSX 详解
一 jsx 的本质是什么? jsx是语法糖,需要被编译成js才能运行. jsx 看似是html 结构,实质是js结构的语法糖,在代码编译阶段被编译成js结构.所以jsx的本质可描述为看似html结构的 ...
- JS中实现Trim(),TrimStart(),TrimEnd() 的方法
//去除字符串头尾空格或指定字符 String.prototype.Trim = function (c) { if (c == null || c == "") { var st ...
- 圆形进度条的模仿3-DrawArc,DrawCircle,DrawText,自定义属性实例讲解
前面两篇中已经讲过如何使用drawARC,等,画其他的图形的方法的使用也是一样的,只是参数不同, 同时也讲了如何通过xml进行自定义属性,接下来这篇便是通过实例讲解如何实地应用起来, 效果如下,点击开 ...
- C# Webservice中如何实现方法重载--(方法名同名时出现的问题)
本文摘抄自:http://blog.sina.com.cn/s/blog_53b720bb0100voh3.html 1.Webservice中的方法重载问题(1)在要重载的WebMethod上打个M ...