Horizontal ScrollView touchables stop responding when nested inside a sticky header (RN 0.79.2)
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- C++
- Estrellas
- 127k
- Forks
- 25.3k
- Merge medio
- 1 d 23 h
- PR fusionados (30 d)
- 4
Descripción
Description
When you nest a horizontal ScrollView with touchable tabs inside a vertical ScrollView (or SectionList) that uses stickyHeaderIndices, the horizontal scroll still works, but the individual tab TouchableOpacity buttons no longer fire their onPress once the header becomes pinned. As soon as you scroll back up and the header unsticks, the buttons work again.
Steps to reproduce
- Create a fresh RN 0.79.2 project (or use your existing app).
- Copy this component into
App.js(or similar):
import React, { useState } from 'react'
import { View, Text, ScrollView, TouchableOpacity, StyleSheet, SafeAreaView } from 'react-native'
const ItemBox = ({ title }) => (
<View style={styles.itemBox}>
<Text>{title}</Text>
</View>
)
export default function NestedScrollTest() {
const tabs = [
{ key: 'one', title: 'Tab One' },
{ key: 'two', title: 'Tab Two' },
{ key: 'three', title: 'Tab Three' },
{ key: 'four', title: 'Tab Four' },
{ key: 'five', title: 'Tab Five' },
]
// Generate lots of items so it scrolls
const allItems = Array.from({ length: 50 }, (_, i) => `Item #${i + 1}`)
const [activeTab, setActiveTab] = useState(tabs[0].key)
const filteredItems = allItems.filter(
(_, idx) => idx % tabs.length === tabs.findIndex(t => t.key === activeTab)
)
return (
<SafeAreaView style={styles.container}>
<TouchableOpacity
style={styles.submitButton}
onPress={() => alert(`Submitting on "${activeTab}"`)}
>
<Text style={styles.submitText}>Top Submit Button</Text>
</TouchableOpacity>
{/* Vertical scroll area with sticky header */}
<ScrollView
style={styles.scrollContainer}
contentContainerStyle={{ paddingBottom: 20 }}
nestedScrollEnabled
removeClippedSubviews={false}
stickyHeaderIndices={[0]}
>
{/* Sticky horizontal tab bar */}
<View style={styles.stickyContainer} pointerEvents="box-none">
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
nestedScrollEnabled
pointerEvents="auto"
contentContainerStyle={styles.tabBar}
onStartShouldSetResponder={() => true}
>
{tabs.map(tab => (
<TouchableOpacity
key={tab.key}
onPress={() => setActiveTab(tab.key)}
activeOpacity={0.7}
style={[
styles.tabButton,
activeTab === tab.key && styles.activeTab,
]}
>
<Text style={
activeTab === tab.key ? styles.activeTabText : styles.tabText
}>
{tab.title}
</Text>
</TouchableOpacity>
))}
</ScrollView>
</View>
{filteredItems.map(title => (
<ItemBox key={title} title={title} />
))}
</ScrollView>
<TouchableOpacity
style={styles.submitButton}
onPress={() => alert(`Submitting on "${activeTab}"`)}
>
<Text style={styles.submitText}>Bottom Submit Button</Text>
</TouchableOpacity>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollContainer: {
flex: 1,
},
stickyContainer: {
backgroundColor: 'white',
zIndex: 10,
elevation: 4,
},
tabBar: {
paddingVertical: 10,
paddingHorizontal: 8,
},
tabButton: {
paddingHorizontal: 16,
paddingVertical: 8,
marginRight: 8,
borderRadius: 4,
backgroundColor: '#EEE',
},
activeTab: {
backgroundColor: '#4A90E2',
},
tabText: {
fontSize: 14,
color: '#333',
},
activeTabText: {
fontSize: 14,
color: '#FFF',
},
itemBox: {
height: 80,
marginHorizontal: 16,
marginVertical: 8,
backgroundColor: '#F9F9F9',
borderRadius: 6,
justifyContent: 'center',
alignItems: 'center',
elevation: 2,
},
submitButton: {
padding: 16,
backgroundColor: '#28A745',
alignItems: 'center',
},
submitText: {
color: '#FFF',
fontSize: 16,
},
})
-
Run on Android.
-
Scroll until the tab bar sticks to the top.
-
Tap any tab button—nothing fires.
-
Scroll up one pixel; tap again—the press now registers.
React Native Version
0.79.2
Affected Platforms
Runtime - Android
Output of npx @react-native-community/cli info
System:
OS: Linux 6.8 Ubuntu 24.04.2 LTS 24.04.2 LTS (Noble Numbat)
CPU: (6) x64 Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
Memory: 12.45 GB / 23.38 GB
Shell:
version: 5.2.21
path: /bin/bash
Binaries:
Node:
version: 22.11.0
path: ~/.nvm/versions/node/v22.11.0/bin/node
Yarn:
version: 1.22.22
path: ~/.nvm/versions/node/v22.11.0/bin/yarn
npm:
version: 10.9.0
path: ~/.nvm/versions/node/v22.11.0/bin/npm
npmPackages:
"@react-native-community/cli":
installed: 18.0.0
wanted: 18.0.0
react:
installed: 19.0.0
wanted: 19.0.0
react-native:
installed: 0.79.2
wanted: 0.79.2
MANDATORY Reproducer
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza con el reproductor obligatorio y su componente App.js en Android, comparando las pulsaciones de las pestañas mientras el encabezado está fijado y sin fijar. Rastrea el manejo táctil de Android en React Native para el ScrollView horizontal anidado y el sticky header, y luego verifica que los controles TouchableOpacity de las pestañas respondan mientras están fijados sin interrumpir el desplazamiento.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- react-native
- Área
- mobile
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Tranquilo
- Claridad
- Bastante claro
- Aptitud para principiantes
- 48/100