【问题标题】:PanResponder could not detect touch if i touch on Touchables(TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback)如果我触摸 Touchables(TouchableHighlight、TouchableOpacity、TouchableWithoutFeedback),PanResponder 无法检测到触摸
【发布时间】:2019-03-15 19:00:53
【问题描述】:

我在我的项目中实现了 PanResponder,但它仅在我触摸不可触摸元素时才有效。当我触摸 TouchableOpacity 等可触摸元素时,PanReponder 没有响应。但是当我在 TouchableOpacity 上移动手指时,PanResponder 会响应。

同样的事情也发生在 Button 身上

请告诉我可能是什么问题。

博览链接:https://snack.expo.io/SyYrtq87W

import React, { Component } from 'react';
import { Button, PanResponder, View, StyleSheet,TouchableOpacity } from 'react-native';
import { Constants } from 'expo';

export default class App extends Component {
  state = {
    show : false
  };
  _panResponder = {};

  componentWillMount() {
    this._panResponder = PanResponder.create({

      onStartShouldSetPanResponder: () => {
        alert('clicked')
        console.log('clicked')
        return true
      },
      onMoveShouldSetPanResponder: () => {
        alert('moved')
        console.log('moved')
        return true
      },
      onStartShouldSetPanResponderCapture: () => false,
      onMoveShouldSetPanResponderCapture: () => false,
      onPanResponderTerminationRequest: () => true,
      onShouldBlockNativeResponder: () => false,
    });
  }

  render() {
    return (
      <View
        style={styles.container}
        collapsable={false}
        {...this._panResponder.panHandlers}>

 {/*********************PanResponder does not respond***************************/}       

        <TouchableOpacity>
          <View style={{width:200, height:200,backgroundColor:'red'}}>
          </View>
        </TouchableOpacity>



        <Button
          title="Here is a button for some reason"
          onPress={() => {}}  
        />

  {/*****************************************************************************/}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
  }
});

【问题讨论】:

  • 您分享的 github 问题与您所说的相反,或者您确实需要重新表述您的问题。 When I touch touchable elements like TouchableOpacity, it does not responds - 谁不回应?可触摸还是响应者?
  • 对不起。是 PanResponder 没有响应。 Touchable 工作正常。
  • 在您提供的链接中,问题是 Touchables 没有响应,所以这是一个不同的问题。我认为响应器对您来说工作正常,如果您希望可触摸不响应,您可以禁用它们的指针事件。
  • 响应者没有正确响应。如果我按下 TouchableOpacity(应用程序中的红色框),则不会弹出警报。如果我稍微拖动手指(有时甚至在单击时),就会弹出红色框警报,并显示消息“已移动”,指示手指已在其上移动。我想要的是,如果我点击那个红框警报应该弹出消息“点击”
  • 哦,如果是这样的话,您添加的链接就像在 iOS 上对我一样。你是在什么平台上遇到这个问题的?

标签: react-native


【解决方案1】:

我遇到了类似的问题。基本上是因为你总是在onStartShouldSetPanResponder 和/或onMoveShouldSetPanResponder 中返回 true,它们将接管该触摸事件。

我的解决方法:不要将触摸视为“您的”(PanResponder 的),除非用户先将其移动了一点您设置的阈值。

const touchThreshold = 20;
const panResponder = PanResponder.create({
    onStartShouldSetPanResponder : () => false,
    onMoveShouldSetPanResponder : (e, gestureState) => {
        const {dx, dy} = gestureState;

        return (Math.abs(dx) > touchThreshold) || (Math.abs(dy) > touchThreshold);
    },
    ...
});

【讨论】:

  • 您提供的解决方案与我的要求相反。我的问题是如果我触摸 touchables,PanResponder 没有响应,Touchables 响应良好。就我而言,Touchables 接管了 PanResponder
  • 在你的例子中,PanResponder 接管了其他触摸事件,但在我的例子中,Touchables 接管了 PanResponder。
  • 这是我想要的解决方案。请注意,您可以使用(e, {dx, dy}) =&gt; { 而不是(e, gestureState) =&gt; { const {dx, dy} = gestureState;
【解决方案2】:

最后它击中了我。这是一个非常愚蠢的错误。 忘记添加alert('clicked') at

onStartShouldSetPanResponderCapture: ()

现在,

onStartShouldSetPanResponderCapture: () =&gt; {alert('clicked') ; return false},

博览链接:https://snack.expo.io/ryWx7lBrb

现在,它无处不在,包括 Touchable 和 Button。

import React, { Component } from 'react';
import { Button, PanResponder, View, StyleSheet,TouchableOpacity } from 'react-native';
import { Constants } from 'expo';

export default class App extends Component {
  state = {
    show : false
  };
  _panResponder = {};

  componentWillMount() {
    this._panResponder = PanResponder.create({

      onStartShouldSetPanResponder: () => {
        alert('clicked')
        return true
      },
      onMoveShouldSetPanResponder: () => true,
      onStartShouldSetPanResponderCapture: () => {alert('clicked') ; return false},
      onMoveShouldSetPanResponderCapture: () => false,
      onPanResponderTerminationRequest: () => true,
      onShouldBlockNativeResponder: () => false,
    });
  }

  render() {
    return (
      <View
        style={styles.container}
        collapsable={false}
        {...this._panResponder.panHandlers}>

 {/*********************PanResponder now responds***************************/}       

        <TouchableOpacity>
          <View style={{width:200, height:200,backgroundColor:'red'}}>
          </View>
        </TouchableOpacity>



        <Button
          title="Here is a button for some reason"
          onPress={() => {}}  
        />

  {/*****************************************************************************/}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
  }
});

【讨论】:

  • 不要为我工作,如果我尝试滚动就会触发警报
【解决方案3】:

如果你设置了这个,Touchables 将无法工作

onStartShouldSetPanResponder: () =&gt; true

这将完全控制触摸。仅当用户开始拖动组件时才进行控制总是一个不错的选择。

onMoveShouldSetPanResponder: () => true

这是 PanResponder 的示例。

    this.panResponder = PanResponder.create({
      onMoveShouldSetPanResponder: () => true,
      onPanResponderMove: (event, gesture) => {
        if (gesture.dy > 0 && this.state.size._value < width) {
          this.state.size.setValue(40 + gesture.dy)
        }
      },
      onPanResponderRelease: () => {
        Animated.spring(this.state.size, {
          toValue: 40
        }).start()
      }
    })

这是我的 JSX 代码。

<Animated.View {...this.panResponder.panHandlers}>
    <TouchableWithoutFeedback onPress={this.openImage}>
        <Animated.Image style={profileImage}
           source={{uri: 'https://example.com/face.jpg'}}/>
     </TouchableWithoutFeedback>
 </Animated.View>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多