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

Fermée
#613 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 2 jours

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
22/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Active
Stack technique
ios, react-native, swift, typescript
Domaine
mobile, mobile-dev

Piste de recherche

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.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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>
  );
}
Langage dominant
TypeScript
Étoiles
1.5k
Forks
112
Merge moyen
2 j 3 h
PR mergées (30 j)
13

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de callstack/react-native-bottom-tabs

Toutes les issues de callstack/react-native-bottom-tabs

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.