🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

Flutter 又迎大坑修改?iOS 26 鍵盤變化可能帶來大量底層改動

又是一個小問題可能帶來的大改動,感覺官方在評估的時候,有點過分細節了。

這個問題來自去年底的 #179482 issue ,Flutter 在 iOS 26 上,某些場景會因為出現半透明鍵盤,而頁面底下本來應該被鍵盤遮擋的 Widget,由於默認沒有被繪製,從而出現鍵盤背景顏色 UI 異常:

image

雖然問題看起來是一個圓角問題,但是實際上這是 iOS 26 系統鍵盤增加了“半透明”後帶來的問題,Flutter 在鍵盤後面那一層在某些場景下沒有正確渲染內容,導致鍵盤半透明區域透出來的不是底下 BottomSheet 的真實內容,而是一整塊黑色區域。

issue 提到問題,問題最明顯的場景主要出現在 iOS 26 的 showModalBottomSheet() 下。

image

為什麼會這樣?首先就是你的 App 目前是否使用了最新 Xcode 26,以及在 Info.plist 裡有沒有使用 UIDesignRequiresCompatibility = YES 讓 App 繼續使用舊的系統設計風格

image image image image

透過上面前兩張圖我們可以看到,iOS 26 正常情況下,系統鍵盤其實是會出現半透明效果並且具備圓角,雖然透明效果不是特別明顯,但是對比後兩張圖里,可以看到微信和淘寶還是保留著原本的 iOS 18 的直角效果。

如果還是保留原本風格,其實並會遇到這個問題。

所以這個 issue 首先是需要在 Xcode 26 下,並且沒有關閉 Liquid Glass 適配的情況下才會遇到,當然,就算是 iOS 26 場景,一般情況下也不會有什麼大問題,比如下圖直接在介面內使用一個 TextField,其實並不會有明顯問題:

image image

問題還是主要出現在類似 showModalBottomSheet 的場景,特別是在背景色透明的時候,雖然我們設定了 backgroundColor: Colors.transparent但是在 Flutter 裡,某些時候 UI 並不會“在鍵盤背後繼續畫”,因為在 iOS 26 之前,Flutter(以及很多跨平台框架)都默認:

系統鍵盤 = 完全不透明的遮擋物,所以 Flutter 的 pipeline 會認為鍵盤區域背後不需要特殊關注。

image image

實際上類似同樣的問題,在 RN 裡也是存在,甚至對於 CMP 來說也是存在不一樣的問題,所以對於 CMP 來說,才會有 1.10 Interop views 新特性 Overlay,用於支持 UIKit 的半透明/blur 可以採樣到 Skia 的內容的實驗性 API :

image

image

image

所以這個問題實際上的本質不是圓角,比如我把 showModalBottomSheet 背景改成紅色,此時你可以看到鍵盤是可以採集到背景色的,甚至我把 Container 也改成紅色,你也看不出來異常:

image image

所以問題更多出現在透明色上,隨著 showModalBottomSheet 彈出並帶有透明色的時候,由於 Flutter 認為被鍵盤這擋住的下層 Widget 並不需要繪製,所以導致系統鍵盤採集不到對應的像素點,從而出現了一開始的黑色背景。

所以其實這個 Bug 如果想臨時解決,只需要在 Info.plist 裡配置 UIDesignRequiresCompatibility = YES 就可以了,只是此時 App UI 會是 iOS 18 的風格:

image image

如果再對比抖音和 Github App,就可以看到 iOS 26 新鍵盤風格對於整體應用的風格影響還是挺大的,所以不少 App 目前會選擇通過關閉適配拖延時間。

image image

那為什麼會說,這個 Bug 會導致整個底層生態的重構?因為 iOS 26 改變了“系統鍵盤會完全遮擋 App 內容”這一長期不變的底層假設,而 Flutter 的渲染 / 佈局 / Insets / 事件系統,幾乎全都建立在舊假設之上,這套邏輯幾乎滲透在:

  • RenderObjectlayout
  • Scaffold / BottomSheet / Navigator
  • MediaQuery
  • TextInputPlugin
  • Engine 中的 view hierarchy
  • ···

image

也就是如果想完全適配這個新場景(多層嵌套下還提供鍵盤場景的透明支持),一旦需要完全支持“鍵盤下內容需要繪製”,就要系統性重構多個核心層,例如:

Framework 層(Dart)

  • MediaQuery.viewInsets
    • 現在代表“不可見區域”
    • 未来要不要拆成多個:coveredInsetsobscuredInsetsvisualInsets
  • Scaffold / BottomSheet
    • 是否仍然自動 resize?
    • 還是只做佈局、不做裁剪?
  • Clip 行為
    • 現在大量 widget 默認不 clip

Engine 層(iOS embedder)

  • FlutterView / UIView hierarchy
  • CALayer 合成順序
  • 系統 keyboard window vs Flutter window
  • 是否需要:
    • 在被遮擋區域繼續 raster
    • 或改變 backing store 策略

輸入系統 & Hit Test

  • 鍵盤下的 widget:
    • 畫出來了
    • 但不能響應觸摸
  • Flutter 目前的 hit-test 假設:
    • “看得見 = 可點”

插件 & 三方生態

  • 各種:
    • bottom sheet 插件
    • keyboard avoiding 插件
    • 聊天 UI
  • 各種涉及“手搓” viewInsets 的場景

所以這個“語義場景”如果發生比變化,那麼涉及的將是大量底層改動,甚至一些性能指標都會需要調整,從長遠來看,這還會是個 iOS 平台特有的差異化適配場景,並且引入大量 break change

最後

最後總結下,正常大家使用輸入框輸入文本內容不會有什麼問題,甚至如果你用 Dialog 場景也不會有什麼問題,甚至你看下方最後一張圖片,在 dialog 下的鍵盤依然可以正常透視工作:

image image image

所以問題主要還是存在於 BottomSheet 這種場景,因為 BottomSheet 默認行為是認為底部對齊,高度有限,所以對於 BottomSheet 會認為底部高度區域在鍵盤下不渲染,所以導致最後採集不到像素出現黑色。

針對問題其實可以選擇配置 UIDesignRequiresCompatibility = YES 來解決,或者替換為 Dialog 來繞過場景,但是如果要等官方修復這個場景,可能會需要等待評估是否真的有必要大規模底層改動。

image

從我的角度看,這完全沒必要,畢竟真這麼修改,帶來的就是生態的大量 break change。

參考鏈接

github.com/flutter/flu…


原文出處:https://juejin.cn/post/7596245612558319625


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝7   💬7   ❤️1
186
🥈
我愛JS
1
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付