[英]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>
.我正在运行 react native 0.24.1,当<TouchableOpacity>
组件放置在<ScrollView>
时,我遇到了问题。
Its onPress events fire fine but there is a special case when they do not.它的onPress事件触发得很好,但有一个特殊情况,当他们没有触发时。 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.如果与<TouchableOpacity>
组件一起有一个<TextInput>
,并且当前焦点位于<TextInput>
框上,那么您可以单击<TouchableOpacity>
并且您将看到它的onPress事件不会被触发。
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.一旦焦点不再位于<TextInput>
,您现在可以按下<TouchableOpacity>
组件,它的onPress事件将正常触发。
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.请注意,如果<TouchableOpacity>
组件放置在<View>
而不是<ScrollView>
一切都按预期工作,并且上述问题不适用。
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>
您可以在上面的代码中将<ScrollView>
替换为<View>
组件,您将看到每次都会触发onPress事件,即使焦点位于<TextView>
NOTE: I am working on Android.注意:我在 Android 上工作。 I have no idea if this happens also on iOS.我不知道这是否也发生在 iOS 上。
NOTE 2: According to Aakash Sigdel, this is indeed happening on iOS too.注意 2:根据 Aakash Sigdel 的说法,这也确实发生在 iOS 上。
Set keyboardShouldPersistTaps={true}
on your ScrollView
.在ScrollView
上设置keyboardShouldPersistTaps={true}
。
Duplicate answer here: https://stackoverflow.com/a/34290788/29493这里有重复的答案: https : //stackoverflow.com/a/34290788/29493
UPDATE: As Hossein writes in his answer, true|false
has been deprecated in newer versions in favor of always|never|handled
.更新:正如侯赛因在他的回答中所写的那样, true|false
在较新的版本中已被弃用,而支持always|never|handled
。
Set keyboardShouldPersistTaps='always'
to your ScrollView
props.将keyboardShouldPersistTaps='always'
为您的ScrollView
道具。
React Native Documentation:反应本机文档:
'never' (the default), tapping outside of the focused text input when the keyboard is up dismisses the keyboard. “从不” (默认值),当键盘向上时在焦点文本输入之外轻敲会关闭键盘。 When this happens, children won't receive the tap.发生这种情况时,儿童将不会收到水龙头。
'always' , the keyboard will not dismiss automatically, and the scroll view will not catch taps, but children of the scroll view can catch taps. 'always' ,键盘不会自动关闭,滚动视图不会捕捉点击,但滚动视图的孩子可以捕捉点击。
'handled' , the keyboard will not dismiss automatically when the tap was handled by a children, (or captured by an ancestor). 'handled' ,当点击被孩子处理(或被祖先捕获)时,键盘不会自动关闭。
false , deprecated, use 'never' instead. false ,已弃用,请改用“从不”。
true , deprecated, use 'always' instead. true ,已弃用,请改用“始终”。
In my case, I was using alignItems:'baseline', when I switched to alignItems:'center' , it started working smoothly.就我而言,我使用的是alignItems:'baseline',当我切换到alignItems:'center' 时,它开始顺利工作。 Don't know why不知道为什么
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.