-
Notifications
You must be signed in to change notification settings - Fork 325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When a touchable component (inside renderHeader) is pressed, snapTo() method doesn't work on Android. #15
When a touchable component (inside renderHeader) is pressed, snapTo() method doesn't work on Android. #15
Comments
I took a look into this and seem to have found the cause. The problem is that after pressing on a Touchable in the header, panMasterState transitions to State.FAILED, but snaps only run if it's State.END. This is a work around which avoids the problem https://github.com/james-macindoe/react-native-gesture-handler/commit/bae1632334cd53ed720380c8ddecdfc89b70dce0 I don't know much about gesture handlers so I'm not sure if this is the correct fix or just a hack. Any suggestions @osdnk? |
This is a fix for osdnk/react-native-reanimated-bottom-sheet#15 If there's a Touchable inside a PanGestureHandler, when you press on the Touchable, the PanGestureHandler will begin() but not activate() (I think because the dy of the pan is too small). The PanGestureHandler then receives the ACTION_UP, which causes it to fail() at the line this PR changes. I'm assuming this is a valid use case that it shouldn't fail() on.
This issue has been fixed after the merge of https://github.com/james-macindoe/react-native-gesture-handler/commit/bae1632334cd53ed720380c8ddecdfc89b70dce0 in |
@roshangm1 snapTo doesn't work with |
Still experiencing this problem with React native paper button |
This is a fix for osdnk/react-native-reanimated-bottom-sheet#15 If there's a Touchable inside a PanGestureHandler, when you press on the Touchable, the PanGestureHandler will begin() but not activate() (I think because the dy of the pan is too small). The PanGestureHandler then receives the ACTION_UP, which causes it to fail() at the line this PR changes. I'm assuming this is a valid use case that it shouldn't fail() on.
## Description The change that this PR reverts was made to fix [this issue](osdnk/react-native-reanimated-bottom-sheet#15) ([which seems to be fixed already](osdnk/react-native-reanimated-bottom-sheet#150)). But by allowing the `PanGestureHandler` to transition from `BEGAN` to the `END` state it introduced a new problem: when a `TapGestureHandler` has a `waitFor` property set with a reference to a `PanGestureHandler` the `TapGestureHandler` will not activate. Here is a quick summary of why it happens: 1. User touches the screen, `ACTION_DOWN` event is sent 2. Both `TapGestureHandler` and `PanGestureHandler` go to `BEGAN` state 3. User lifts the finger, `ACTION_UP` event is sent 4. `TapGestureHandler` tries to become active but has to wait for the `PanGestureHandler` to resolve 5. `PanGestureHandler` transitions to the `END` state 6. Because `PanGestureHandler` did not fail it is assumed it was recognized and all handlers waiting for it are cancelled With this change at step 5. `PanGestureHandler` transitions to the `FAILED` state, and `TapGestureHandler` becomes active, which is expected behavior. Besides that, [the original problem seems to be fixed in another way](osdnk/react-native-reanimated-bottom-sheet#150). ## Test plan This code sample demonstrates the problem and allows to check the solution: ```js import React, { Component } from 'react'; import { createRef } from 'react'; import { StyleSheet, View } from 'react-native'; import { TapGestureHandler, PanGestureHandler, } from 'react-native-gesture-handler'; function getState(s: number) { switch (s) { case 0: return "Undetermined"; case 1: return "Failed"; case 2: return "Began"; case 3: return "Cancelled"; case 4: return "Active"; case 5: return "End"; } return s; } export default class Example extends Component { constructor(props: Record<string, never>) { super(props); this.panHandler = createRef<PanGestureHandler>(); } render() { return ( <PanGestureHandler onHandlerStateChange={(e) => console.log(`Pan: ${getState(e.nativeEvent.state)}`)} ref={this.panHandler}> <View style={styles.home}> <TapGestureHandler onHandlerStateChange={(e) => console.log(`Tap: ${getState(e.nativeEvent.state)}`)} waitFor={this.panHandler}> <View style={styles.button} /> </TapGestureHandler> </View> </PanGestureHandler> ); } } const styles = StyleSheet.create({ home: { width: '100%', height: '100%', alignSelf: 'center', backgroundColor: 'plum', }, button: { width: 100, height: 100, backgroundColor: 'green', alignSelf: 'center', }, }); ```
I was trying to perform snapTo to hide bottomsheet when header is tapped. I wasn't able to do so Android. However, it works on iOS.
It can be reproduced in this snack. (Took one of the snack from earlier issues)
Long press the "Profile" tab to show the bottom sheet.
https://snack.expo.io/@roshangm1/bottom-sheet
I would like to dig in more on this (doing it too). If you have any clue on what could be the possible reason for this behavior, please do let me know.
The text was updated successfully, but these errors were encountered: