React-native-gesture-handler: How to lock the PanGesture handler into a single direction at a time?

Created on 29 Nov 2018  路  4Comments  路  Source: software-mansion/react-native-gesture-handler

I would like my view to move in the X or Y axis but never at the same time.
I have two nested PanGestureHandler (maybe it's possible to use a single one as well, I'm not sure):

     <PanGestureHandler
        onHandlerStateChange={onGestureEventY}
        onGestureEvent={onGestureEventY}
      >
        <Animated.View style={{ flex: 1 }}>
          <PanGestureHandler
            onHandlerStateChange={onGestureEventX}
            onGestureEvent={onGestureEventX}
          >
              // ....
          </PanGestureHandler>
        </Animated.View>
      </PanGestureHandler>
    );

I would like to active one when moving through X so the Y moving is ignored and vice versa.
I looked this part of the documentation: https://kmagiera.github.io/react-native-gesture-handler/docs/interactions.html but it doesn't seem to support this use case.

How could this recipe be achieved?

Most helpful comment

After reading the documentation more careful, I found the solution to my problem. All <PanGestureHandlers> must wrap a <Animated.View>. Then I can use wait for and set the right conditions for one of the pan handler to fail to recognize a gesture. See example below.

     <PanGestureHandler
        onHandlerStateChange={onGestureEventX}
        onGestureEvent={onGestureEventX}
        ref={this.horizontalHandler}
        minDist={10}
        failOffsetY={[-10, 10]}
      >
        <Animated.View style={{ flex: 1 }}>
          <PanGestureHandler
            waitFor={this.horizontalHandler}
            onHandlerStateChange={onGestureEventY}
            onGestureEvent={onGestureEventY}
          >
            <Animated.View style={{ flex: 1 }}>
         //...
            </Animated.View>
          </PanGestureHandler>
        </Animated.View>
      </PanGestureHandler>

All 4 comments

After reading the documentation more careful, I found the solution to my problem. All <PanGestureHandlers> must wrap a <Animated.View>. Then I can use wait for and set the right conditions for one of the pan handler to fail to recognize a gesture. See example below.

     <PanGestureHandler
        onHandlerStateChange={onGestureEventX}
        onGestureEvent={onGestureEventX}
        ref={this.horizontalHandler}
        minDist={10}
        failOffsetY={[-10, 10]}
      >
        <Animated.View style={{ flex: 1 }}>
          <PanGestureHandler
            waitFor={this.horizontalHandler}
            onHandlerStateChange={onGestureEventY}
            onGestureEvent={onGestureEventY}
          >
            <Animated.View style={{ flex: 1 }}>
         //...
            </Animated.View>
          </PanGestureHandler>
        </Animated.View>
      </PanGestureHandler>

@wcandillon do you have a snack of this by chance?

Okay so the approach with having multiple pan responders didn't work for me. It was too buggy. This is what I did instead. I took a variable translateDirection, initialised it with no direction -1. And when the state was active, calculated which direction should the view move in with a simple translation.y and translation.x comparison. Then when the direction was set, I only change the translateX or translateY depending on the direction:
`cond(eq(state, State.ACTIVE), [

    cond(
      eq(translateDirection, -1),
      cond(
        greaterThan(translation.y, translation.x),
        set(translateDirection, 2),
        set(translateDirection, 1)
      )
    ),
    cond(
      neq(translateDirection, -1),
      cond(
        eq(translateDirection, 1),
        set(translateX, add(offsetX, translation.x)),
        set(translateY, translation.y)
      )
    ),
  ]),`
Was this page helpful?
0 / 5 - 0 ratings

Related issues

jhalborg picture jhalborg  路  5Comments

brunolemos picture brunolemos  路  3Comments

enahum picture enahum  路  4Comments

brentvatne picture brentvatne  路  5Comments

brentvatne picture brentvatne  路  4Comments