与父PanResponder的TouchableOpacity

时间:2017-11-30 08:23:33

标签: react-native gestures

我的父母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>

谢谢

7 个答案:

答案 0 :(得分:13)

我的案例的解决方案是修改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)                  
}

答案 1 :(得分:2)

完美!由于敏感,我只需要进行调整。

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

答案 2 :(得分:1)

this.panResponder = PanResponder.create({
    onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
});

答案 3 :(得分:0)

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

以下是具有平移视图和按钮的组件的示例代码。

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

我有同样的问题。该解决方案是上述解决方案的组合。必须为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)
  },

答案 6 :(得分:-1)

似乎每个人的情况都略有不同……这是E1=D1个对我有用的属性的组合(我试图允许点按进入子元素,但使用PanResponder捕获动作:< / p>

PanResponder.create

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