[iOS 26] Re-tapping the selected tab emits no tabPress for middle tabs (UIKit never calls the delegate)

Offen
#613 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
22/100
Issue-Typ
Bug
Klarheit
Größtenteils klar
Aktivitätsstatus
Aktiv
Tech-Stack
ios, react-native, swift, typescript
Bereich
mobile, mobile-dev

Rechercherichtung

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.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

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.swift in 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", tabBarActiveTintColor set; tabs 1–4 use sfSymbol icons and one tab a template image icon
Steps to reproduce
  1. Create a navigator with 5 tabs via createNativeBottomTabNavigator.
  2. Add a listeners={{ tabPress: () => console.log('tabPress', route.name) }} to each Tab.Screen (or useScrollToTop in each root).
  3. On an iOS 26.2 simulator, switch to tab 2, then tap tab 2 again.
  4. Expected: tabPress for the re-tap (and useScrollToTop scrolls). 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>
  );
}
Vorherrschende Sprache
TypeScript
Sterne
1.5k
Forks
111
Ø Merge
1 T. 13 Std.
Gemergte PRs (30 T.)
8

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus callstack/react-native-bottom-tabs

Alle Issues in callstack/react-native-bottom-tabs

Ähnliche Issues

Weitere Issues zu TypeScript

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.