背景

当我在 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 上没有异常?的更多相关文章

  1. 旧版本APP被开发人员下架,新版本重新上传依然显示被下架

    新接了一个项目,这个项目在苹果商城上面的版本已经被原来另外一家公司的开发人员下架.我们重新设计.开发.上传,申请加急审核,终于完成手动发布.但是发布成功后,新版本提示:被开发人员下架.以前虽然迭代开发 ...

  2. IOS如何下载旧版本应用APP

    前言 文章相对来说比较复杂,特别是查找版本ID对应的步骤,这里推荐使用另一种方案,操作起来更简单. 本文介绍如何使用Workflow及Fiddler下载IOS旧版本APP应用. 实现原理 通过Work ...

  3. 下载历史版本App超详细教程

    有些时候我们需要下载旧版本的 App 进行研究或者其他用途,然而在 iOS 下,苹果的 App Store 里面默认只能下载最新版本的 App,对滴,就是这么任性,不服不行.然而在 Android 里 ...

  4. 下载历史版本App

    文/timhbw(简书作者)原文链接:http://www.jianshu.com/p/edfed1b1822c著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 1.软件准备 [必备]C ...

  5. 青花瓷运用->下载历史版本App

    1.软件准备 [必备]Charles4.0.1 下载密码: jfnk [不需要,配合Charles食用效果更佳]Paw2.3.1 下载密码: t3my 2.正式开始 2.1 打开Charles青花瓷 ...

  6. 混合式App开发 Apicloud 官方iPhone X 适配

    iPhone X 适配 由于iPhone X的特殊造型,为了方便开发者对iPhone X进行适配,苹果在iOS 11中引入了Safe Area的概念,引擎也在api对象下添加了safeArea属性和s ...

  7. 利用 Charles Proxy 下载旧版本 iOS App

    一.软件准备 1.旧版本 iTunes1.IPSW Downloads:https://ipsw.me/2.百度网盘链接: https://pan.baidu.com/s/1PO9Z12o-rqZ_J ...

  8. python3.7环境下创建app,运行Django1.11版本项目报错SyntaxError: Generator expression must be parenthesized

    咳咳!!! 今天用命令行创建django项目中的app应用,出现了这样一个错误 这个错误在python3.6版本下安装运行django 1.11版本正常运行,但python3.7版本下运行django ...

  9. python3.7环境下创建app、运行Django1.11版本项目报错Generator expression must be parenthesized

    有些同学喜欢追求新鲜感~但追求新鲜感终归是要付出一点点代价的 在编程领域有一句至理名言:用东西不要用最新的! 就像每次苹果系统的升级都会有相当一部分用户的手机成砖一样 下面我们就介绍一个因版本升级带来 ...

随机推荐

  1. Go | Go 使用 consul 做服务发现

    Go 使用 consul 做服务发现 目录 Go 使用 consul 做服务发现 前言 一.目标 二.使用步骤 1. 安装 consul 2. 服务注册 定义接口 具体实现 测试用例 3. 服务发现 ...

  2. win10简单方法安装杜比v4音效!win10 1909适用!

    先下载这个! 链接: https://pan.baidu.com/s/1zAOOf-1aCJsjBgy36SiGWA 密码: s9n7 这个是杜比V4文件,257MB大小,适用32位64位系统!下 载 ...

  3. node将js中的json对象生成到新的excel表中

    第一步  安装依赖包   npm install json2xls fs 第二步  创建node.js文件,文件内代码如下: var fs = require('fs'); var path = re ...

  4. 实验四  CSS样式的应用

    实验四  CSS样式的应用 注意:以下实验项目皆以本文件为操作对象,实验结果用记事本保留后预览,最后将添加的CSS代码转载到实验报告中 另本网页中蓝色加下划线的字即为默认的超链接样式 实验目的: 掌握 ...

  5. python练习三角形,99乘法

    #方案一:# result=0# #列# for i in range(1,10):# #行# for j in range(1,i+1):# result=i*j# print('%d*%d=%d' ...

  6. 多测师讲解python ____字典,字符,元组,集合(转换)___高级讲师肖sir

    1.字符转换 a =['a','b','c','d','e'] #定义一个列表b =[1,2,3,4,5] #定义一个列表c=zip(a,b)# zip类:可以将两个列表进行拼接,返回一个列表且列表中 ...

  7. MeteoInfoLab脚本示例:AIRS Grid HDF数据

    AIRS Grid HDF数据是HDF4 EOS格式,数据地理坐标信息可以被MeteoInfo自动识别,脚本程序更为简单.需要注意的是读取数据时Y轴是反向的(卫星数据通常如此).脚本程序: #Add ...

  8. MeteoInfo脚本示例:GrADS to netCDF

    这里给出一个将GrADS数据文件转为netCDF数据文件的脚本示例程序,其它格式数据转netCDF可以参考: #-------------------------------------------- ...

  9. pyquery 匹配NavigableString

    pyquery 匹配NavigableString不像xpath那样精确找打匹配对象,只需匹配包含NavigableString的根节点

  10. .Net Core单元测试规范

    .Net Core单元测试规范 一. 前言 为了有效提升代码质量,保证DevOps的顺利进行.将全面开始采用单元测试进行覆盖,届时单元测试将完全纳入 到完整的持续构建生命周期中做为第一道质量把控的门槛 ...