[iOS 15] Header buttons stop responding after pushing and popping a screen over the pager
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 58/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- ios, react-native, swift, typescript
調査の方向性
Start with ios/PagerViewProvider.swift and inspect how setupView() creates the hosting controller; the proposed workaround belongs in a separate PagerViewIOS15NavigationBarCompat.swift file. Reproduce push then pop on an iOS 15 simulator and check whether the navigation bar covers the header buttons. Done means the buttons respond after returning, while iOS 16 and later retain the existing behavior.
索引モデルが issue の本文から書いたものです。
説明
Environment
- react-native-pager-view 9.0.4 in the repro app; the relevant code (
PagerViewProvider.setupView()) is unchanged in 9.0.9 - iOS 15.2 simulator (the reporter also reproduced it on a 15.1 device; newer iOS versions are not affected)
- React Native 0.84.1, New Architecture (Fabric)
@react-navigation/{native,stack,bottom-tabs,material-top-tabs}v7,react-native-screens4.27
Description
On iOS 15, after pushing a screen on top of a screen that contains a PagerView and then going back, the React Navigation header buttons (headerLeft / headerRight) stop responding. They never fire again for that screen.
The cause is not React Navigation. On iOS 15 UIHostingController installs SwiftUI's UIKitNavigationBarBridge, which calls -[UINavigationController setNavigationBarHidden:NO] on the enclosing navigation controller whenever the hosting view appears. react-native-screens creates an RNSContainerNavigationController with a hidden bar for the bottom-tab hasTwoStates container; the bridge re-shows an empty UINavigationBar on top of the screen — exactly over the React Navigation header — and that bar swallows every touch there.
Measured with lldb on an iOS 15.2 simulator after push → pop:
UINavigationBar in the window |
what hitTest at the header button returns |
|
|---|---|---|
| before | present at (0 47; 428 44), hidden = NO |
_UINavigationBarContentView (not the button) |
| after the proposed fix | none visible | the React Native button view |
Breakpoint trace of the cause (on -[UINavigationController setNavigationBarHidden:animated:], hidden = NO):
#0 -[UINavigationController setNavigationBarHidden:animated:]
#1 SwiftUI.UIKitNavigationBarBridge.hostingControllerWillAppear(animated:)
#2 SwiftUI._UIHostingView.viewControllerWillAppear(...)
#3 SwiftUI.UIHostingController._viewWillAppear(_:)
...
#16 -[RNSScreenContainerView attachScreen:atIndex:] ← react-native-screens re-attaches the screen on pop
Reproducible Demo
https://github.com/zewillze/react-native-pager-view-ios15-issue
- Run the repro on an iOS 15.x simulator/device.
- Tap a list row (pushes
Detailinside a@react-navigation/stack). - Go back.
- Tap the "Button" or "+" header button — nothing happens.
The screen structure matters: bottom tabs → stack (with a JS header) → material top tabs (the pager). The bottom-tab container provides the hidden UINavigationController, and the pager's UIHostingController is what triggers the bridge when it re-appears.
Optional check without touches, after step 3 — dump the window hierarchy:
po [[[UIApplication sharedApplication] keyWindow] performSelector:@selector(recursiveDescription)]
Before: a UINavigationBar at (0 47; 428 44) with hidden = NO. After the fix: none.
Proposed fix
Wrap the UIHostingController created in ios/PagerViewProvider.swift so it restores the enclosing navigation bar's hidden state around viewWillAppear.
To keep it easy to drop with iOS 15, the workaround lives in its own file (PagerViewIOS15NavigationBarCompat.swift) and every entry point returns early on iOS 16+ via if #available(iOS 16, *). Deleting that file and replacing the single call site with UIHostingController(...) is all that is needed once iOS 15 support is removed — the same isolation pattern used for the iOS 15 scrollEnabled fix (#1148).
The change is 2 files (+68/−1), preserves 9.0.9's ignoreSafeArea: true behaviour, and I have verified it on an iOS 15.2 simulator. I'll open a PR referencing this issue.
- 主要言語
- TypeScript
- スター
- 3.4k
- フォーク
- 485
- 平均マージ
- 2日 11時間
- マージ済み PR(30日)
- 26
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
callstack/react-native-pager-view のほかの issue
-
[iOS] Focused TextInput keeps focus and keyboard after switching pages (v9)対応中かも @TaduJR が 1 日前に担当しました。 オープン
難易度 4/5 1〜2日 初心者へのやさしさ 69/100
callstack/react-native-pager-view#1192 ·
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 73/100
callstack/react-native-pager-view#1191 ·
メンテナーはふだん 1 日以内に返信
-
iOS: PagerScrollDelegate proxies to itself and overflows the stack when the weak originalDelegate dies対応中かも @lvlrSajjad が 37 日前に担当しました。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
callstack/react-native-pager-view#1146 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
callstack/react-native-pager-view#1144 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
callstack/react-native-pager-view#1141 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
callstack/react-native-pager-view の issue をすべて見る
似ている issue
-
engine-rs P3 review-deferral wasm
難易度 2/5 1〜3時間 初心者へのやさしさ 77/100
maniator/verticopolis#1154 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
メンテナーはふだん 1 日以内に返信
-
Bug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
telerik/kendo-react#3861 ·
メンテナーはふだん 1 日以内に返信
-
[bug]: use-mobile.ts uses pixel logic, causing UI state de-sync with Tailwind CSS rem breakpointsオープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
task
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100