背景

当我在 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. ansible-主机清单的配置

    1. ansible主机清单的配置 以下是ansible安装完成后的源文件 1 [root@test-1 ~]# cat /etc/ansible/hosts 2 # This is the defa ...

  2. 使用phpword获取doc中的表格数据

    1. 首先确定使用phpword是可以读取word文档中表格里面的数据, 使用的phpword版本0.17.0 2.理解word文档内容的存储逻辑规则(这里只做简单概述) 一般做博文喜欢直接贴代码,直 ...

  3. 【UR #9】App 管理器

    UOJ小清新题表 题目内容 UOJ链接 一句话题意:给出一个强联通的混合图,有一些有向边和无向边.删除一些边使其维持强联通的状态,求删边方案. 数据范围 \(1\leq n\leq 5000,0\le ...

  4. swoft实现自动重启服务 转

    目的:1.上传代码后HTTP服务自动重启,不需要自己手动执行:php bin/swoft http:start2.自动重启适用于开发调试阶段,因为不能再后台运行所以在线上环境的话还是要重启http服务 ...

  5. matplotlib 饼状图

    import matplotlib.pyplot as plt import matplotlib as mpl # 支持中文 plt.rcParams['font.sans-serif'] = [' ...

  6. minianaconda3安装

    wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh chmod +x Miniconda3-lates ...

  7. CUDA和cuDNN的安装

    CUDA软件 Windows 打开NVIDIA CUDA网站,选择需要下载的版本,依次选择Windows平台,x86_64架构,10系统,exe(local)本地安装包,再选择Download即可下载 ...

  8. 普通人如何站在时代风口学好AI?这是我看过最好的答案

    摘要:当前,数据.算法.算力的发展突破正推动AI应用的逐步落地. AI是什么? 根据维基百科的定义,人工智能是一种新的通用目的技术(GPT, General Purpose Technology),它 ...

  9. python提取视频第一帧图片

    一.实现代码 # -*- coding: utf-8 -*- import cv2 from PIL import Image from io import BytesIO def tryTime(m ...

  10. pybind11和numpy进行交互

    使用一个遵循buffer protocol的对象就可以和numpy交互了.   这个buffer_protocol要有哪些东西呢? 要有如下接口: struct buffer_info { void ...