[iOS 26] Re-tapping the selected tab emits no tabPress for middle tabs (UIKit never calls the delegate)
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 22/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- ios, react-native, swift, typescript
- 領域
- mobile, mobile-dev
調査の方向性
Start with ios/TabItemEventModifier.swift, specifically the TabBarDelegate and where handle(tabController:) installs it, and reproduce on an iOS 26 simulator with the five-tab sample. The report says UIKit never calls shouldSelect for re-taps of tabs 2–4, so the cause likely lies in how the delegate is replaced on each SwiftUI update. Done means a re-tap on any tab emits tabPress to JS, confirmed by the sample's listener logs.
索引モデルが issue の本文から書いたものです。
説明
Before submitting a new issue
- I tested using the latest version of the library, as the bug might be already fixed. (Observed on 1.4.0.
ios/TabItemEventModifier.swiftin 1.5.0 is byte-identical to 1.4.0, so the reselect path is unchanged.) - I tested using a supported version of react native.
- I checked for possible duplicate issues, with possible answers. (Related but different: #461, #464.)
Bug summary
On iOS 26.2 with 5 tabs, re-tapping the already selected tab emits tabPress only for some tabs. In our app it is emitted for the first tab, but not for tabs 2–4: no tabPress reaches JS, so useScrollToTop and pop-to-root on re-select never run there.
I instrumented TabBarDelegate in ios/TabItemEventModifier.swift with NSLog in tabBarController(_:shouldSelect:), in tabBarController(_:shouldSelectTab:) (logged before the iOS 27 guard), and where handle(tabController:) installs the delegate. For a re-tap of tabs 2–4, UIKit calls neither delegate method. Switching to those same tabs is reported normally, and the delegate is installed and alive at that moment: the next switch after a missed re-tap is logged. So the event is not dropped in the library's JS or Swift. UIKit does not ask UITabBarControllerDelegate about this re-select at all.
Log (simulator, compact; idx = tapped tab, same = selectedViewController == viewController):
shouldSelectVC idx=Optional(0) selectedIdx=0 same=Y vcType=TabHostingController <- re-tap tab 1: reported
shouldSelectVC idx=Optional(1) selectedIdx=0 same=N vcType=TabHostingController <- switch to tab 2
handle delegate set; existing=<…TabBarDelegate: 0x600000504760>
<- re-tap tab 2 (x3, 1.5–3 s apart): nothing
shouldSelectVC idx=Optional(2) selectedIdx=1 same=N vcType=TabHostingController <- switch to tab 3
handle delegate set; existing=<…TabBarDelegate: 0x60000054c4a0>
<- re-tap tab 3: nothing
shouldSelectVC idx=Optional(3) selectedIdx=2 same=N vcType=TabHostingController <- switch to tab 4
handle delegate set; existing=<…TabBarDelegate: 0x600000568260>
<- re-tap tab 4: nothing
shouldSelectVC idx=Optional(0) selectedIdx=3 same=N vcType=TabHostingController <- switch to tab 1
shouldSelectVC idx=Optional(0) selectedIdx=0 same=Y vcType=TabHostingController <- re-tap tab 1: reported
shouldSelectTab: was never called for any tap. Side observation: a new TabBarDelegate instance is installed on every SwiftUI body update (handle delegate set after each switch).
The last tab's re-tap was also reported in some runs and not in others. I can't say whether that is related to #461.
Library version
react-native-bottom-tabs 1.4.0, @bottom-tabs/react-navigation 1.4.0 (1.5.0's TabItemEventModifier.swift is identical)
Environment info
- iOS 26.2 simulator (iPhone 15 and iPhone SE 3rd gen), Xcode 26.2
- react-native 0.81.5 (New Architecture), Expo SDK 54
- @react-navigation/native 7.5.0, react-native-screens 4.16.0
- 5 tabs,
scrollEdgeAppearance="transparent",minimizeBehavior="onScrollDown",tabBarActiveTintColorset; tabs 1–4 usesfSymbolicons and one tab a template image icon
Steps to reproduce
- Create a navigator with 5 tabs via
createNativeBottomTabNavigator. - Add a
listeners={{ tabPress: () => console.log('tabPress', route.name) }}to eachTab.Screen(oruseScrollToTopin each root). - On an iOS 26.2 simulator, switch to tab 2, then tap tab 2 again.
- Expected:
tabPressfor the re-tap (anduseScrollToTopscrolls). Actual: no event for tabs 2–4; the first tab's re-tap is reported.
Reproducible sample code
import { createNativeBottomTabNavigator } from '@bottom-tabs/react-navigation';
const Tab = createNativeBottomTabNavigator();
const log = (name: string) => ({ tabPress: () => console.log('tabPress', name) });
export function Tabs() {
return (
<Tab.Navigator scrollEdgeAppearance="transparent" minimizeBehavior="onScrollDown">
{['A', 'B', 'C', 'D', 'E'].map((n) => (
<Tab.Screen key={n} name={n} component={Screen} listeners={log(n)}
options={{ tabBarIcon: () => ({ sfSymbol: 'circle' }) }} />
))}
</Tab.Navigator>
);
}
- 主要言語
- TypeScript
- スター
- 1.5k
- フォーク
- 111
- 平均マージ
- 1日 13時間
- マージ済み PR(30日)
- 8
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
callstack/react-native-bottom-tabs のほかの issue
-
renderBottomAccessoryView crashes on iOS 26: RCTBottomAccessoryComponentView does not initialize _props in its constructor対応中かも @oleksandrzavarzin-callstack が 1 日前に担当しました。 オープンbug
難易度 1/5 1時間未満 初心者へのやさしさ 92/100
callstack/react-native-bottom-tabs#607 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
[iOS] Fabric: SIGABRT on tab press when tab key contains non-ASCII characters (kCFStringEncodingUTF8 passed to -cStringUsingEncoding:)対応中かも @oleksandrzavarzin-callstack が 4 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
callstack/react-native-bottom-tabs#560 ·
メンテナーはふだん 1 日以内に返信
-
[iOS] A scroll view above the main list stops `minimizeBehavior="onScrollDown"`.対応中かも @oleksandrzavarzin-callstack が今日担当しました。 オープンbug
難易度 4/5 3〜5日 初心者へのやさしさ 18/100
callstack/react-native-bottom-tabs#617 ·
メンテナーはふだん 1 日以内に返信
-
[iOS] Tabs don't fire tabLongPress event on iOS 26対応中かも @thiagobrez が 44 日前に担当しました。 オープンbug
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
callstack/react-native-bottom-tabs#573 ·
メンテナーはふだん 1 日以内に返信
-
iOS: allow opting out of the private-CoreSVG SVG decoder (exclude_files by default, or an opt-in flag)対応中かも @oleksandrzavarzin-callstack が 11 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
callstack/react-native-bottom-tabs#565 ·
メンテナーはふだん 1 日以内に返信
callstack/react-native-bottom-tabs の issue をすべて見る
似ている issue
-
needs investigation
難易度 2/5 1〜3時間 初心者へのやさしさ 60/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
area:visualizer tech-debt
難易度 2/5 1時間未満 初心者へのやさしさ 66/100
jmbarzee/temporal-architect#292 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
riverqueue/river#1576 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
colbymchenry/codegraph#3228 ·
メンテナーはふだん 1 日以内に返信