Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TouchableOpacity with parent PanResponder

Tags:

I have a parent PanResponder with a child TouchableOpacity. What happens is that the TouchableOpacity doesn't respond to clicks because the PanResponder takes the click. I have tried to follow this guide but no success: http://browniefed.com/blog/react-native-maintain-touchable-items-with-a-parent-panresponder/

this is my code:

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) => {
            },
        });

and this is my View :

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

Thank you

like image 953
Maxim Toyberman Avatar asked Nov 30 '17 08:11

Maxim Toyberman


People also ask

How to make a view respond properly to touches?

A wrapper for making views respond properly to touches. On press down, the opacity of the wrapped view is decreased, dimming it. Opacity is controlled by wrapping the children in an Animated.View, which is added to the view hierarchy.

How to create touchable opacity in React Native?

React Native - TouchableOpacity Step1 - Create File. First we need to create src/components/home/TouchableOpacity.js file. Step 2 - Logic. This is just a simple container component with no additional functionality. Step 3 - Presentation. Presentational component is a simple button with some ...

What is the use of inherits touchablewithoutfeedback?

Inherits TouchableWithoutFeedback Props. Determines what the opacity of the wrapped view should be when touch is active. Defaults to 0.2. (Apple TV only) Object with properties to control Apple TV parallax effects. enabled: If true, parallax effects are enabled.

Is there a way to handle touch-based input?

If you're looking for a more extensive and future-proof way to handle touch-based input, check out the Pressable API. A wrapper for making views respond properly to touches. On press down, the opacity of the wrapped view is decreased, dimming it.


2 Answers

The solution for my case was to modify 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)                  
}
like image 172
Maxim Toyberman Avatar answered Sep 22 '22 14:09

Maxim Toyberman


Perfect! I just needed to adjust because of the sensitivity.

onMoveShouldSetPanResponder: (evt, gestureState) => {
      const { dx, dy } = gestureState
      return dx > 2 || dx < -2 || dy > 2 || dy < -2
}
like image 27
Florian Bonniec Avatar answered Sep 24 '22 14:09

Florian Bonniec