2016-04-24 177 views
10

我正在运行反应原生0.24.1,并且当它被放置在<ScrollView>中时,我遇到<TouchableOpacity>组件的问题。React Native:TouchableOpacity onPress问题在滚动视图

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

您可以用<View>部件更换<ScrollView>在上面的代码,每次你会看到,onPress事件触发,即使当焦点是对<TextView>

注:我在Android上工作。我不知道这是否也发生在iOS上。

注2:根据Aakash Sigdel,这确实是发生在iOS上了。

+0

尝试使用其中一个keyboardDismissMode = {'none','ondrag','interactive'} – Mihir

+0

我在iOS上检查过它,并且可以确认这也发生在iOS中。 –

+0

我有一个与ScrollView旁边的类似的问题,但是在移除ScrollView时问题并未解决。相反,我将按钮的大小增加到了最小推荐尺寸44x44。之后,该按钮可识别所有轻击事件。 –

回答

14

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

重复的答案在这里:https://stackoverflow.com/a/34290788/29493

UPDATE:作为侯赛因写在他的回答,true|false已过时,有利于always|never|handled较新版本。

+1

感谢您的帮助哥们:) –

4

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

阵营本地文档:

“从不”(默认),攻聚焦文字输入之外,当键盘了驳回键盘。发生这种情况时,儿童不会收到水龙头。

'always',键盘不会自动关闭,并且滚动视图不会触摸水龙头,但滚动视图的子项可以捕捉水龙头。

'处理',当水龙头由儿童处理时(或由祖先捕获),键盘不会自动关闭。

false,已弃用,请使用'never'代替。

true,已弃用,请改用'always'。