admin管理员组

文章数量:1415467

Right now, I return a true in my onStartShouldSetPanResponder, and as a result the PanResponder wants to handle taps AND pans. Is there any way to restrict it to just pans, as I want a TouchableHighlight to handle that? (I get that the Gesture Responder should handle both, but it seems weird that the "Pan" Responder handles taps)

Since the gesture is just starting, the dx/dy are 0 in onStartShouldSetPanResponder. Is there any way to detect if it's the start of a tap and return false, if so?

Or should I just detect whether it was a tap or pan in the OnPanResponderRelease?

Right now, I return a true in my onStartShouldSetPanResponder, and as a result the PanResponder wants to handle taps AND pans. Is there any way to restrict it to just pans, as I want a TouchableHighlight to handle that? (I get that the Gesture Responder should handle both, but it seems weird that the "Pan" Responder handles taps)

Since the gesture is just starting, the dx/dy are 0 in onStartShouldSetPanResponder. Is there any way to detect if it's the start of a tap and return false, if so?

Or should I just detect whether it was a tap or pan in the OnPanResponderRelease?

Share Improve this question edited Sep 24, 2021 at 0:14 Alex Wayne 187k52 gold badges328 silver badges360 bronze badges asked Aug 8, 2017 at 16:52 user1985427user1985427 3633 silver badges11 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

I was able to acplish this through the onMoveShouldSetPanResponder method as follows:

onMoveShouldSetPanResponder: (evt, gestureState) => {
    return Math.abs(gestureState.dx) >= 1 || Math.abs(gestureState.dy) >= 1
}

If the x or y movement is greater than 1, return true. In order to then detect a tap, I had to wrap everything within my view containing the panHandlers with a touchable element. Here is a full working example:

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

export default function App() {
  return (
    <View>
      <CircleTapExample/>
    </View>
  );
}

class CircleTapExample extends Component {
    constructor(props) {
        super(props)
        this.position = new Animated.ValueXY({ x: 0, y: 0 });
        this.panResponder = PanResponder.create({
            onMoveShouldSetPanResponder: (evt, gestureState) => {
              return Math.abs(gestureState.dx) >= 1 || Math.abs(gestureState.dy) >= 1
            },
            onPanResponderMove: (evt, gestureState) => {
                console.log("I was moved")
                this.position.setValue({ x: gestureState.moveX, y: gestureState.moveY })
            },
        });
    }
    
    circleTapped() {
        // Do something here when tapped
        console.log("I was tapped")
    }
    
    render() {
        return (
            <Animated.View style={[styles.container, { ...this.position.getLayout() }]} {...this.panResponder.panHandlers}>
                <TouchableOpacity onPress={() => this.circleTapped()} style={{ flex: 1 }}>
                    <View style={styles.circle} />
                </TouchableOpacity>
            </Animated.View>
        )
    }
}

const styles = StyleSheet.create({
  container: {
      width: 75,
      height: 75,
      bottom: 5,
      left: 5,
      position: 'absolute'
  },
  circle: {
      width: 75,
      height: 75,
      borderRadius: 40,
      backgroundColor: 'red'
  }
});

<div data-snack-id="YskU-lxRe" data-snack-platform="web" data-snack-preview="true" data-snack-theme="light" style="overflow:hidden;background:#F9F9F9;border:1px solid var(--color-border);border-radius:4px;height:505px;width:100%"></div>
<script async src="https://snack.expo.dev/embed.js"></script>

The panResponder has two events :

  • onStartShouldSetPanResponder(Capture)
  • onMoveShouldSetPanResponder(Capture)

I've been able to solve this problem only by removing onStartShouldSetPanResponderCapture.

本文标签: