背景
10月14日 iPhone 12 系列正式發(fā)布辐益,當我觀看直播看到介紹 iPhone 12 系列的分辨率后,我注意到這些分辨率是全新的脱吱,我立即在群里吐槽——又需要適配一波了智政。我以為只是寬高變化會導致字號、間距的變化箱蝠,然而更嚴重的問題是我們判斷是否是劉海屏使用了如下代碼(這種寫法是不完善的续捂,但我相信很多 App 里都是這么寫的);
self.is_iphonex = (SCREEN_MAX_LENGTH==812.f || SCREEN_MAX_LENGTH==896.f);
是否是劉海屏是枚舉所有符合預期的設備高度來判斷的宦搬,它的好處是快速穩(wěn)定牙瓢,但遇到新機型就悲催了。
在新 iPhone 12 系列中间校,屏幕高度分別為:
Device | Retina | 屏幕點(pt) | 物理像素 (px) |
---|---|---|---|
iPhone 12 Pro Max 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_LENGTH==812.f || SCREEN_MAX_LENGTH==896.f
) 代碼來判斷劉海屏一罩,定位導航欄位置肯定是錯誤的。預期表現(xiàn)是導航欄被劉海遮住撇簿。
實際情況如何呢?
巡查App Store 的 App 在 iPhone 12 的表現(xiàn)
當我拿到藍色 iPhone 12 的第一件事情就是看看各個 App 在適配方面有哪些異常表現(xiàn)差购,大概看了10 幾個 App四瘫,除了 斗魚,嗶哩嗶哩 外大部分適配都沒有大問題欲逃。
有問題找蜜,我不意外,但是其他 App 稳析,包括我們自己的 App洗做,全屏的界面導航都沒問題。
為什么有些 OK彰居,有些異常诚纸?
經(jīng)過實際測試,用 Xcode 12.0 和 Xcode 12.1 分別在真機 iPhone 12 上運行陈惰;發(fā)現(xiàn) Xcode 12.1 build 的 App 真機運行是有問題的畦徘。目前 App Store 里運行有問題的 App,如斗魚抬闯,都是用了最新版本 Xcode 12.1 上傳的 ipa井辆。
所以二者的的差別在哪里?
觀察到溶握, Xcode 12.1 里已經(jīng)有 iPhone 12 的模擬器杯缺,所以說 Xcode 12.1 是認識 iPhone 12 的∷埽回想幾年前當 iPhone X 出現(xiàn)時萍肆,舊的 App 是如何在 iPhone X 上表現(xiàn)的—— App 運行在屏幕的中間袍榆,上下部分都留有黑邊,表現(xiàn)如我找到網(wǎng)絡圖:
這里引出所謂的兼容模式匾鸥。
蘋果 App 的向后兼容規(guī)則
當 App 運行在自己不認識的新設備上時蜡塌,系統(tǒng)會把新設備當做上一代的設備來使用。換言之勿负,新設備運行的 App 在兼容模式馏艾,避免 App 去處理 build 之時還不存在的設備上邏輯。
小貼士:
關于如何選擇上一代設備奴愉,大規(guī)則是選擇和新設備尺寸最接近的舊設備或者獨立分辨率來兼容琅摩,每個新設備對應的上一代設備都不一樣。讀者可以查看參考鏈接 1锭硼,文章寫的非常詳細房资,強烈推薦閱讀。
這個兼容規(guī)則也用著顯示模式的設置里(在用戶在設置 -> 顯示和亮度 -> 放大顯示 里設置了放大效果)檀头。
例如轰异, iPhone 11 Pro Max 標準顯示(Standard Zoom) 下分辨率是 414×896 points;而如果設置為放大顯示(Display Zoom)會被當做 iPhone 11 Pro 設備暑始,此時分辨率是 375×812 points搭独。當設備運作在兼容模式,大部分設備的一些常見的高度廊镜,如 statusbar牙肝、 bottombar 的尺寸會被影響。
真實 iPhone 11 Pro 的頂部安全距離是 44嗤朴,底部安全距離是 34配椭;而 iPhone 11 Pro Max 運行在放大顯示(Display Zoom)下,雖然屏幕分辨率和 iPhone 11 Pro 相同雹姊,但頂部安全距離卻是 40股缸,底部安全距離是 31;
除了運行在兼容模式吱雏,退化為舊設備分辨率外乓序,iPhone 還有一種尺寸適配策略:downsampling,例如全新一代的 iPhone12 mini坎背,被當做 iPhone 11 Pro 渲染即 375×812 points替劈,如果按照3x 圖渲染,實際的渲染像素是 1125 x 2436得滤,在 1080×2340 pixel 屏幕上顯示不下陨献,需要 downsampling / 1.04,不能按照 3x 圖渲染懂更;這樣導致它的頂部安全距離是奇葩的 50 pt眨业。
關于如何 downsampling 急膀,這里用 8P 的渲染示例,截圖取自
結論
因為用 Xcode 12.0 打的 ipa龄捡,在 iPhone 12 上運行在兼容模式卓嫂,尺寸是 iPhone 11,重點是頂部安全距離聘殖、底部安全距離都和 iPhone 11 保持一致晨雳,所以不會有問題;而用 Xcode 12.1 打的包奸腺,采用全新的分辨率運行餐禁,如果沒有適配,肯定出問題突照。
因為今年疫情的影響導致蘋果產(chǎn)品發(fā)布流程被打亂帮非,出現(xiàn)了 Xcode 版本早于 iPhone 真機上市的情況,導致一些線上 App 在新機上有兼容問題讹蘑。
附錄
1末盔、正確判斷是否是劉海屏的方法,蘋果會推薦我們使用 safeAreaInsets 來獲取座慰。如從 ViewController.view 獲取時庄岖,時機太遲了,需要從更早創(chuàng)建的地方獲取如 keyWindow角骤,如:
+ (CGFloat)topOffset{
if (@available(iOS 11, *)) {
return [UIApplication sharedApplication].keyWindow.safeAreaInsets.top;
// 其實也有隱患,如果是從推送打開 App 心剥,可能還不存在 keyWindow
}
return 20;
}
直接使用 topOffset 來設置頂部安全距離或者通過判斷 bottomOffset 是否大于 0 來確認是否是劉海屏邦尊,進而設置不同尺寸。
2优烧、如果是判斷劉海屏然后再加 statusbar 高度的作法(不推薦)蝉揍,你還需要完整的 statusbar 高度的表;
iPhone11: 48
iPhone12/12 pro/12 pro max: 47
iPhone12 mini: 50
iPad Pro畦娄、IPad Air: 24
Other iPhones: 44
非劉海屏:20
參考
[1] https://links.jianshu.com/go?to=https%3A%2F%2Fhacknicity.medium.com%2Fhow-ios-apps-adapt-to-the-various-iphone-12-screen-sizes-e45c021e1b8b
[2] https://links.jianshu.com/go?to=https%3A%2F%2Fdeveloper.apple.com%2Fvideos%2Fplay%2Fwwdc2019%2F224%2F%3Ftime%3D123
[3]https://links.jianshu.com/go?to=https%3A%2F%2Fwww.paintcodeapp.com%2Fnews%2Fultimate-guide-to-iphone-resolutions