はじめに
Flutterアプリを iPadOS 26.3 で動作確認していたところ、AppBar上のボタンから PopupMenu や Dialog などのオーバーレイを開いた瞬間に、すぐ閉じてしまう問題に遭遇しました。
Androidでは発生せず、iPadOS 18でも発生しませんでした。
また、自分の環境では Flutter 3.38.10 では再現し、Flutter 3.41.0 へ上げると解消しました。
ただし、Flutter 3.41.0〜3.41.2には、この修正に関連して別のクラッシュ不具合があるようなので、実際にこの問題を解決する目的でFlutterを上げるなら、3.41.3以上 にするのがよさそうです。
再現方法
AppBar上のボタンをタップすれば必ず発生するというより、ステータスバーに近いボタン上部あたりをタップしたとき に発生しやすいことが分かりました。
例えば、AppBar の IconButton 中央よりも少し上側、つまりステータスバーに近い位置をタップすると、 Dialog や PopupMenu などのオーバーレイが開いた直後に閉じる症状が発生します。
発生した症状
AppBarに置いたボタンからオーバーレイを開くと、表示された直後に閉じてしまいました。
イメージとしては、次のような挙動です。
- AppBar のボタンをタップ
- オーバーレイが一瞬表示される
- 勝手にすぐ閉じる
原因
こちらの Issue #177992 では、iPadOS 26.1でオーバーレイが開いた直後に閉じる問題が報告されています。
また、このIssueには found in release: 3.35 / found in release: 3.38 のラベルが付いていました。
自分の環境では、iPadOS 26.3 + Flutter 3.38.10でも同様の症状が発生しました。
自分の環境では、iOS / Android / iPadOS 18では発生せず、iPadOS 26.3 でのみ発生しました。
Issue #177992 でも、iPadOS では発生する一方で、iPhone 端末では再現しないケースとして報告されています。
iOS / iPadOSには、ステータスバー付近をタップするとスクロールビューを一番上に戻す挙動があります。
Flutterもその挙動を再現するために、Flutter側の古い実装では、iOS側からステータスバータップが通知されたときに、Flutter framework側へ画面左上 (0, 0) の疑似タップとして伝えていました。
しかしFlutter framework側では、その疑似タップが通常のタップイベントのように扱われることがあり、開いた直後のオーバーレイが「外側をタップされた」と判断して閉じてしまったことが原因のようです。
流れとしては、以下のようなイメージです。
- AppBarのボタン上部をタップ
- オーバーレイが開く(
Dialogなど) - Flutter側に
(0, 0)の疑似タップが流れる - オーバーレイの外側タップとして扱われる
- 開いた直後に閉じる
つまり、ボタンの onPressed や showDialog の書き方が直接悪かったというより、ステータスバー付近のタップをFlutterが疑似タップとして扱っていたことで、開いた直後のオーバーレイが「外側をタップされた」と誤判定して閉じていた、という問題のようです。
対応方針
根本対応としては、Flutter SDK を更新するのがよいと思います。
自分の検証では Flutter 3.41.0 で即閉じ問題は解消しましたが、3.41.3 に関連 hotfix が入っているため、3.41.3 以上を使うのが無難だと思います。
Flutter 3.41.0〜3.41.2 では、即閉じ問題関連の修正に伴って、iOS でステータスバーをタップしたときに、Scaffold の body に置かれた ListView のような、その画面のメインの縦スクロール (primary scroll view) がまだレイアウトされていないとクラッシュする可能性があったようで、その hotfix が入ったようです。
Flutter の CHANGELOG には、3.41.3 の hotfix として以下の記載があります。
Tapping on the status bar may crash the app on iOS when there's a primary scroll view that has never been laid out.
上記の問題については、Issue #182233 に記載されていました。
一時回避策
すぐにFlutterのバージョンを上げられない場合、Dialog であれば barrierDismissible: false にすることで、外側タップによる即閉じを避けられると思います。
MenuAnchor や PopupMenuButton の場合は、遅延を入れて疑似タップをやり過ごしてから開くみたいな対応が考えられます。
ですが、Flutter SDKを更新するほうがよいと思います。
まとめ
-
発生条件: iPadOS 26.1以降の環境で発生する可能性がある問題として報告されており、自分の環境ではiPadOS 26.3で再現しました
※自分の検証ではiOS / Android / iPadOS 18 では発生しませんでした。 - 発生バージョン: 自分の環境では、Flutter 3.38.10では発生し、Flutter 3.41.0では解消しました
- 推奨する対策: 3.41.0〜3.41.2にはステータスバー関連の別クラッシュがあるようなので、この問題の対策としてFlutterを更新する場合は、少なくとも 3.41.3以上 を使うのがよさそうです
参考
- Overlays close immediately after opening on iPadOS 26.1 #177992
- Dialogs and dismissible overlays close immediately when opened from buttons in upper screen area on iPadOS 26.1 #178086
- PopupMenuButton menu closes immediately after opening (iPadOS) #178714
- Send statusBarTouch events via dedicated messages #179643
- ScrollController.animateTo crashes when status bar is tapped on iOS #182233
- Reland #179643, only scroll hit-testable primary scroll views on status bar tap #182391
- Flutter CHANGELOG
