2016-04-24 5 views
10

Ich bin reagierende native 0.24.1 ausgeführt und ich habe ein Problem mit der <TouchableOpacity> Komponente, wenn es in einem <ScrollView> platziert wird.React Native: TouchableOpacity onPress Probleme in einem ScrollView

Seine onPress Ereignisse Feuer gut, aber es gibt einen speziellen Fall, wenn sie nicht tun. Wenn zusammen mit der <TouchableOpacity> Komponente haben Sie eine <TextInput>, und der aktuelle Schwerpunkt liegt auf der <TextInput> Box, dann können Sie auf die <TouchableOpacity> klicken und Sie werden sehen, die onPress Ereignis wird nicht ausgelöst werden.

Zumindest das erste Mal, wenn Sie es tun. Sobald der Fokus nicht mehr auf der <TextInput> ist, können Sie jetzt auf die <TouchableOpacity> Komponente drücken und die onPress Ereignis wird nur gut ausgelöst.

Beachten Sie, dass, wenn die <TouchableOpacity> Komponente innerhalb einer <View> anstelle von <ScrollView> platziert wird, alles wie erwartet funktioniert und das obige Problem nicht zutrifft.

Hier ist ein Code, das Problem zu demonstrieren:

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

Sie können die <ScrollView> mit einem <View> Komponente auf dem obigen Code ersetzen, und Sie werden, dass onPress Ereignis ausgelöst wird jedes Mal sehen, auch wenn der Fokus ist auf dem <TextView>

HINWEIS: ich auf Android arbeitete. Ich habe keine Ahnung ob das auch auf iOS passiert.

Anmerkung 2: Nach Aakash Sigdel, dies in der Tat geschieht auf iOS zu.

+0

versuchen Sie es mit einer der TastaturDismissMode = {'keine', 'ondrag', 'interaktiv'} – Mihir

+0

Ich überprüfte es auf iOS und kann bestätigen, dass dies auch in iOS geschieht. –

+0

Ich hatte ein ähnliches Problem mit einer neben einer ScrollView, aber das Problem wurde beim Entfernen der ScrollView nicht behoben. Stattdessen habe ich die Größe meiner Schaltfläche auf die empfohlene Mindestgröße von 44x44 erhöht. Danach erkannte der Button alle Tap-Ereignisse. –

Antwort

14

Setzen Sie keyboardShouldPersistTaps={true} auf Ihre ScrollView.

doppelte Antwort hier: https://stackoverflow.com/a/34290788/29493

UPDATE: Wie Hossein in seiner Antwort schreibt, true|false wurde in neueren Versionen für always|never|handled veraltet.

+1

Danke für die Hilfe Kumpel :) –

4

Set keyboardShouldPersistTaps='always' zu Ihrem ScrollView Requisiten.

Reagieren Mutter Dokumentation:

‚nie‘ (Standardeinstellung), außerhalb der fokussierten Texteingabe tippen, wenn die Tastatur der Tastatur ist bis entlässt. Wenn dies geschieht, erhalten Kinder den Wasserhahn nicht.

'immer', die Tastatur wird nicht automatisch ausgeblendet und die Bildlaufansicht fängt keine Taps ab, aber Kinder der Bildlaufansicht können Taps erfassen.

"behandelt", die Tastatur wird nicht automatisch entlassen, wenn der Hahn von einem Kind behandelt wurde, (oder von einem Vorfahren gefangen).

false, veraltet, verwenden Sie stattdessen "nie".

true, veraltet, verwenden Sie stattdessen "immer".