【问题标题】:React Native: TouchableOpacity onPress problems inside a ScrollViewReact Native:ScrollView 中的 TouchableOpacity onPress 问题
【发布时间】:2016-08-17 18:30:02
【问题描述】:

我正在运行 react native 0.24.1,当 <TouchableOpacity> 组件放置在 <ScrollView> 中时遇到问题。

它的 onPress 事件可以正常触发,但有一种特殊情况不会触发。 如果与<TouchableOpacity> 组件一起,您有一个<TextInput>,并且当前焦点在<TextInput> 框上,那么您可以单击<TouchableOpacity>,您将看到它的onPress 事件不会被解雇。

至少在你第一次这样做的时候。一旦焦点不再在<TextInput> 上,您现在可以按下<TouchableOpacity> 组件,它的 onPress 事件将正常触发。

请注意,如果将 <TouchableOpacity> 组件放置在 <View> 而不是 <ScrollView> 内,则一切正常,上述问题不适用。

这里有一些代码来演示这个问题:

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);

您可以将上述代码中的&lt;ScrollView&gt; 替换为&lt;View&gt; 组件,您会看到每次都会触发onPress 事件,即使焦点位于&lt;TextView&gt; 上也是如此 p>

注意:我正在使用 Android。我不知道这是否也发生在 iOS 上。

注意 2:根据 Aakash Sigdel 的说法,iOS 上也确实发生了这种情况。

【问题讨论】:

  • 尝试使用其中一个keyboardDismissMode={'none', 'ondrag','interactive'}
  • 我在 iOS 上检查过,可以确认 iOS 也有这种情况。
  • 我在 ScrollView 旁边的 也遇到了类似的问题,但是在移除 ScrollView 时问题没有得到解决。相反,我将按钮的大小增加到推荐的最小尺寸 44x44。之后,按钮识别所有点击事件。

标签: android scrollview react-native


【解决方案1】:

在您的ScrollView 上设置keyboardShouldPersistTaps={true}

此处重复答案:https://stackoverflow.com/a/34290788/29493

更新:正如 Hossein 在他的回答中所写,true|false 在较新的版本中已被弃用,取而代之的是 always|never|handled

【讨论】:

  • 感谢好友的帮助:)
【解决方案2】:

keyboardShouldPersistTaps='always' 设置为您的 ScrollView 道具。

React Native 文档:

'从不'(默认),当键盘向上时在焦点文本输入之外点击会关闭键盘。发生这种情况时,孩子们不会收到点击。

'always',键盘不会自动关闭,滚动视图不会捕捉点击,但滚动视图的子视图可以捕捉点击。

'handled',当孩子处理敲击(或祖先捕获)时,键盘不会自动关闭。

false,已弃用,请改用“从不”。

true,已弃用,改用“always”。

【讨论】:

  • 如果对任何人有帮助,同样的问题仅在iPhone X 上发生在我身上,在iPhone 6 plus 上没有发生
【解决方案3】:

就我而言,当我切换到 alignItems:'center' 时,我正在使用 alignItems:'baseline',,它开始顺利运行。不知道为什么

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-14
    • 1970-01-01
    • 2018-08-20
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    相关资源
    最近更新 更多