【问题标题】:TouchableOpacity with parent PanResponder带有父 PanResponder 的 TouchableOpacity
【发布时间】:2017-11-30 08:23:32
【问题描述】:

我有一个父母 PanResponder 和一个孩子 TouchableOpacity。 发生的情况是TouchableOpacity 没有响应点击,因为PanResponder 接受了点击。 我试图遵循本指南但没有成功: http://browniefed.com/blog/react-native-maintain-touchable-items-with-a-parent-panresponder/

这是我的代码:

this._panResponder = PanResponder.create({
            onStartShouldSetPanResponder: (evt, gestureState) => true,
            onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
            onMoveShouldSetResponderCapture: () => true,
            onMoveShouldSetPanResponder: (evt, gestureState) => true,
            onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
                return gestureState.dx != 0 && gestureState.dy != 0;
            },
            onPanResponderGrant: (evt, gestureState) => {
                let isFirst = gestureState.y0 > 164 ? false : true;
                this.setState({animObj: isFirst, isUsingCurtain: true});
            },
            onPanResponderMove: (evt, gestureState) => {

                //let Y = this.state.animObj ? gestureState.moveY - this.state.currentHeaderHeight  : gestureState.moveY - this.state.currentHeaderHeight ;// - this.state.currentHeaderHeight;
                let Y = gestureState.moveY - this.state.currentHeaderHeight + 20
                if (Y < 0) {
                    return false
                }
                this.state.animCurtain.setValue(Y);
                gestureState.moveY > height / 2 ? this.setState({curtainOnMiddle: true}) : this.setState({curtainOnMiddle: false})
            },
            onPanResponderTerminationRequest: (evt, gestureState) => true,
            onPanResponderRelease: (evt, gestureState) => {
                if (((height / 2) > gestureState.moveY)) {//slide back up1
                    this._CurtainAnimation(0, false);
                } else {//slide to bottom
                    let val = height - calcSize(180);
                    this._CurtainAnimation(val, true);
                }
            },
            onPanResponderTerminate: (evt, gestureState) => {
            },
            onPanResponderStart: (e, gestureState) => {
            },
        });

这是我的观点:

<Animated.View
            style={[styles.bottomHPHeader, TopArroOpacity ? {opacity: TopArroOpacity} : ""]} {...this._panResponder.panHandlers}>
            <TouchableOpacity onPress={() => this._animateAutoCurtain()}>
                {this.state.curtainOnMiddle ?
                    <AIIcon image={require('../../../../assets/images/homepage/close_drawer_arrow.png')}
                            boxSize={30}/>
                    : <AIIcon image={require('../../../../assets/images/homepage/open_drawer_arrow.png')}
                              boxSize={30}/>}
            </TouchableOpacity></Animated.View>

谢谢

【问题讨论】:

    标签: react-native gestures


    【解决方案1】:

    我的情况的解决方案是修改onMoveShouldSetPanResponder

    onMoveShouldSetPanResponder: (evt, gestureState) => {
        //return true if user is swiping, return false if it's a single click
                    return !(gestureState.dx === 0 && gestureState.dy === 0)                  
    }
    

    【讨论】:

      【解决方案2】:

      完美!由于灵敏度,我只需要调整。

      onMoveShouldSetPanResponder: (evt, gestureState) => {
            const { dx, dy } = gestureState
            return dx > 2 || dx < -2 || dy > 2 || dy < -2
      }
      

      【讨论】:

      • 如果我能给你更多的选票,我会的。谢谢!我的手指很胖,不知道如何调整灵敏度。这是完美的
      • 这个工作正常。但我没有检查负数,而是改为 Math.abs:return Math.abs(gestureState.dx) &gt; 2 || Math.abs(gestureState.dy) &gt; 2;
      【解决方案3】:

      我也有同样的问题。解决方案是上述解决方案的组合。必须为 onMoveShouldSetPanResponder 和 onMoveShouldSetPanResponderCapture 添加一个条件。这就是我所做的。

       onMoveShouldSetPanResponder: (_, gestureState) => {
          const { dx, dy } = gestureState
          return (dx > 2 || dx < -2 || dy > 2 || dy < -2)
        },
        
      onMoveShouldSetPanResponderCapture: (_, gestureState) => {
          const { dx, dy } = gestureState
          return (dx > 2 || dx < -2 || dy > 2 || dy < -2)
        },

      【讨论】:

      • 你这该死的救生员!我挣扎了好几个小时,试图理解为什么没有一个可触摸的对象在使用 PanResponder 的 AnimatedView 中工作。它应该写在 panResponder 内部的任何东西都不能发出它的可触摸事件的地方,除非 PanResponder 是“不活动的”
      • 很高兴帮助 Topsy!您也可以尝试从'react-native-gesture-handler' 导入TouchableOpacity。这也可能表现得更好/修复这样的实例。
      【解决方案4】:
      this.panResponder = PanResponder.create({
          onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
      });
      

      【讨论】:

        【解决方案5】:

        我遇到了类似的问题,但对我来说,有一个包含平移视图的容器视图,同时将按钮置于绝对位置并将其保持在平移视图上方确实有帮助。它不适合所有人,但对于按钮可以绝对定位的情况(例如我的情况),它可以工作。

        这是一个包含平移视图和按钮的组件的示例代码。

        import React, { Component } from "react";
        import {
          Animated,
          View,
          Text,
          StyleSheet,
          PanResponder,
          TouchableOpacity
        } from "react-native";
        
        
        export class ToolRuler extends Component {
        
          constructor(props) {
            super(props);
            this.state = {
              moveX: 0,
              moveY: 0
            };
          }
        
          componentWillMount() {
            this._panResponder = PanResponder.create({
              onStartShouldSetPanResponder: (evt, gestureState) => true,
              onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
              onMoveShouldSetResponderCapture: () => true,
              onMoveShouldSetPanResponder: (evt, gestureState) => true,
              onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
              onPanResponderGrant: (evt, gestureState) => {
                // anything
              },
              onPanResponderMove: (evt, gestureState) => {
                this.setState({
                  moveX: gestureState.moveX,
                  moveY: gestureState.moveY
                });
              },
              onPanResponderTerminationRequest: (evt, gestureState) => true,
              onPanResponderRelease: (evt, gestureState) => {
                this.setState({
                  moveX: gestureState.moveX,
                  moveY: gestureState.moveY
                });
              },
              onPanResponderTerminate: (evt, gestureState) => {},
              onPanResponderStart: (e, gestureState) => {}
            });
          }
        
          render() {
            return (
              <View
                style={{
                  flex: 1,
                  position: "relative",
                  alignItems: "center",
                  justifyContent: "center"
                }}
              >
                <Animated.View
                  {...this._panResponder.panHandlers}
                  style={{ flex: 1, width: "100%", backgroundColor: "#ccc" }}
                >
                  <Text style={{ marginTop: 200, textAlign: "center" }}>
                    x: {this.state.moveX}, y: {this.state.moveY}
                  </Text>
                </Animated.View>
        
                <TouchableOpacity
                  style={{
                    position: "absolute"
                  }}
                  onPress={() => alert("I am tapped!")}
                >
                  <Text>Click Me</Text>
                </TouchableOpacity>
              </View>
            );
          }
        }
        

        【讨论】:

          【解决方案6】:

          我的 Android 解决方案。所有其他人返回false

          onMoveShouldSetPanResponder: (evt, { dx, dy }) => dx !== 0 || dy !== 0,
          

          【讨论】:

            【解决方案7】:

            似乎对每个人都适用的情况略有不同...这是对我有用的PanResponder.create 属性的组合(我试图允许点击子元素,但使用 PanResponder 捕捉动作:

            onStartShouldSetPanResponder:        ( e, state ) => false,
            onStartShouldSetPanResponderCapture: ( e, state ) => false,
            onMoveShouldSetPanResponder:         ( e, state ) => true,
            onMoveShouldSetPanResponderCapture:  ( e, state ) => true,
            

            我希望这对其他人有所帮助,并且它不会以某种方式再次困扰我!

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-03-30
              • 1970-01-01
              • 1970-01-01
              • 2019-03-20
              • 2017-08-18
              • 1970-01-01
              相关资源
              最近更新 更多