This issue was originally posted on StackOverflow but no-one has given a solution for it. On the other hand, users have verified that the issue is there and is present on both iOS and Android:
See: http://stackoverflow.com/questions/36822391/react-native-touchableopacity-onpress-problems-inside-a-scrollview
I am running react native 0.24.1 and I am experiencing an issue with the <TouchableOpacity> component when it is placed inside an <ScrollView>.
Its onPress events fire fine but there is a special case when they do not.
If along with the <TouchableOpacity> component you have a <TextInput>, and the current focus is on the <TextInput> box, then you may click on the <TouchableOpacity> and you will see its onPress event WILL NOT be fired.
At least the first time you do it. Once the focus is NOT on the <TextInput> anymore, you can now press on the <TouchableOpacity> component and its onPress event will fire just fine.
Note that if the <TouchableOpacity> component is placed inside a <View> instead of an <ScrollView> everything works as expected and the above issue does not apply.
Here is some code to demonstrate the problem:
const React = require('react-native');
const {
Component,
Dimensions,
View,
ScrollView,
Text,
TextInput,
TouchableOpacity,
} = React;
// ----------------------------------------------------------------------------
class TouchableOpacityTest extends Component {
constructor(props, context) {
super(props, context);
this.state = {count_onPress:0,count_onPressIn:0,count_onPressOut:0,count_onLongPress:0};
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
onPressEvent(what,e) {
console.log('what:',what);
let newState = {};
newState['count_'+what] = ++this.state['count_'+what];
this.setState(newState);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
render() {
let touchableProps = {
onPress: this.onPressEvent.bind(this,'onPress'),
onPressIn: this.onPressEvent.bind(this,'onPressIn'),
onPressOut: this.onPressEvent.bind(this,'onPressOut'),
onLongPress: this.onPressEvent.bind(this,'onLongPress'),
}
return (
<View style={{flex:1,flexDirection:'column',justifyContent:'flex-start',alignItems:'center',backgroundColor:'blue'}} >
<ScrollView style={{width:Dimensions.get('window').width*0.9,backgroundColor:'red'}}>
<TextInput style={{backgroundColor:'rgb(200,200,200)',marginTop:14}}
placeholder="Focus on me,hide keyboard,and click on text below"
autoCorrect={false}
/>
<TouchableOpacity {...touchableProps} >
<Text style={{fontSize:20,backgroundColor:'pink',marginTop:14}}>
Click on me!{"\n"}
onPress:{this.state.count_onPress}{"\n"}
onPressIn:{this.state.count_onPressIn}{"\n"}
onPressOut:{this.state.count_onPressOut}{"\n"}
onLongPress:{this.state.count_onLongPress}{"\n"}
</Text>
</TouchableOpacity>
</ScrollView>
</View>
);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
// ----------------------------------------------------------------------------
AppRegistry.registerComponent('react_native_app1', () => TouchableOpacityTest);
You may replace the <ScrollView> with a <View> component on the above code and you will see that onPress event fires every time, even when the focus is on the <TextView>
According to some users, this is ALSO happening on iOS too.
Thanks.
Alex
I tend to think this is a feature.
I think the idea behind this current behavior (that you describe a bug) is that when you focus an input, you also should have a keyboard opened, and the first tap outside that occurs should close the keyboard (blur the input) but should not trigger anything else.
That said, I don't think this behavior should be the only available behavior. I don't know how, but we should have a way to configure that some touchable should still receive this event. For instance, in case you tap another input ( see https://github.com/facebook/react-native/issues/4087 )
Hello!
My thoughts with regards to this issue:
<View> than when using a <ScrollView>. The behavior should be equal on both scenarios.+1. I am having the same problem.
Any Touchables require two taps if inside <ScrollView>.
This issue affects quite common layouts, like having a search textinput along with a list of results.
Anytime you enter a new search and get the list of results, you need to click on a give result TWICE for the event to be really triggered.
Quite bad.
I only have the problem on IOS, but not android. 2 taps to get a button press if a text view has the focus.
My text view is inside a ScrollableTabView. Anyone got a nice solution?
I am also facing this issue on android while trying to make an autocomplete textview.
Here's a sample project that shows the solution, which is simply to use
<ScrollView keyboardShouldPersistTaps={true}>
See example 3.
<ScrollView
scrollEnabled={true}
showsVerticalScrollIndicator={true}
keyboardShouldPersistTaps={true}
keyboardDismissMode='on-drag'
>
@facebook-github-bot answered
Closing this issue as @satya164 says the question asked has been answered. Please help us by asking questions on StackOverflow. StackOverflow is amazing for Q&A: it has a reputation system, voting, the ability to mark a question as answered. Because of the reputation system it is likely the community will see and answer your question there. This also helps us use the GitHub bug tracker for bugs only.
Thank you so much !! Now it's working for me
If you have a form and some inputs inside and setting keyboardShouldPersistTaps true doesn't work because after triggering onPress function, the keyboard will come back, You can manually hide the keyboard in onPress function using Keyboard.dimiss()
Most helpful comment
Here's a sample project that shows the solution, which is simply to use
<ScrollView keyboardShouldPersistTaps={true}>See example 3.