Repository navigation
fix(ios): deliver long presses on modern tab bars - #587
thiagobrez wants to merge 1 commit into
Conversation
|
I tested this with a Setup: the repro from #596 (Home, Search with
Selecting the tab still works; only the event goes to the wrong route. Cause: For the fix: looking the position up in Xcode 27.1, iOS 27.0, after long-pressing Favorites: App.tsximport * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeBottomTabNavigator } from '@bottom-tabs/react-navigation';
const Tab = createNativeBottomTabNavigator();
const LastLongPress = React.createContext('none');
const screen = (label) => () => {
const last = React.useContext(LastLongPress);
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>{label}</Text>
<Text>{`tabLongPress: ${last}`}</Text>
</View>
);
};
const Home = screen('Home screen');
const Search = screen('Search screen');
const Favorites = screen('Favorites screen');
const Library = screen('Library screen');
export default function App() {
const [last, setLast] = React.useState('none');
const listeners = (name) => ({ tabLongPress: () => setLast(name) });
return (
<LastLongPress.Provider value={last}>
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name="Home"
component={Home}
listeners={listeners('Home')}
options={{ tabBarIcon: () => ({ sfSymbol: 'house.fill' }) }}
/>
<Tab.Screen
name="Search"
component={Search}
listeners={listeners('Search')}
options={{
role: 'search',
tabBarIcon: () => ({ sfSymbol: 'magnifyingglass' }),
}}
/>
<Tab.Screen
name="Favorites"
component={Favorites}
listeners={listeners('Favorites')}
options={{ tabBarIcon: () => ({ sfSymbol: 'heart.fill' }) }}
/>
<Tab.Screen
name="Library"
component={Library}
listeners={listeners('Library')}
options={{ tabBarIcon: () => ({ sfSymbol: 'rectangle.stack.fill' }) }}
/>
</Tab.Navigator>
</NavigationContainer>
</LastLongPress.Provider>
);
} |

PR Description
Long presses on modern iOS tab bars select a tab but do not deliver the expected
tabLongPressevent. Their buttons live outside the legacyUITabBarhierarchy, and UIKit expands and duplicates them during its native hold animation.Observe touches from the tab controller's view, recognize modern and legacy tab buttons, and capture the route when the touch begins. Resolve vertical and horizontal order (including RTL), ignore the system More destination, and allow UIKit's gestures to continue. Reuse the recognizer while refreshing its callback.
Fixes #573.
How to test?
Open Native Bottom Tabs from Chat and hold Article for one second. Its callback changes the label to New Article. Verify normal Chat selection still works and Contacts still prevents selection.
Verified with agent-device 0.20.10 on:
Native Xcode build and lint pass. Workspace tests and typecheck pass on the common upstream base. UIKit tab-button class inspection remains an implementation dependency, as in the previous recognizer.
Screenshots
02-long-press-before-no-callback.mp4
02-long-press-after-callback.mp4