Skip to content

Conversation

@m-bert
Copy link
Contributor

@m-bert m-bert commented Oct 20, 2025

Description

Some changes in #3740 required follow up.

Tap

Turns out that we can leave triggerAction in reset (thank you apple for transparent docs that clearly describe what changed between 18.5 and 26 ❤️).

It also seems that double onFinalize issue is fixed on 26.

Fling

Removing [self triggerAction] from reset broke things on old iOS. Unfortunately now swiping in different direction does not result in calling onFinalize - this should be handled by triggerAction in reset, but now by default recognizers in reset have Possible state (once again, thank you apple 😄). To fix that we will probably have to rewrite fling to custom logic.

LongPress

LongPress was missing on triggerAction call that sends fail.

Pan

In Pan, I've moved triggerAction calls from touches* methods to interactions* methods.

Test plan

Tested on basic-example and the following code:
import { StyleSheet, View, Text } from 'react-native';

import {
  GestureHandlerRootView,
  Gesture,
  GestureDetector,
  GestureType,
} from 'react-native-gesture-handler';

function TestBox({
  gestureType,
  bgColor,
}: {
  gestureType: GestureType;
  bgColor: string;
}) {
  const handlerName = gestureType.handlerName;

  const gesture = gestureType
    .onBegin(() => {
      console.log(`[${handlerName}] onBegin`);
    })
    .onEnd(() => {
      console.log(`[${handlerName}] onEnd`);
    })
    .onFinalize(() => {
      console.log(`[${handlerName}] onFinalize`);
    })
    .runOnJS(true);

  return (
    <View style={styles.center}>
      <Text>{handlerName}</Text>
      <GestureDetector gesture={gesture}>
        <View style={[styles.box, { backgroundColor: bgColor }]} />
      </GestureDetector>
    </View>
  );
}

export default function App() {
  return (
    <GestureHandlerRootView style={[{ flex: 1, padding: 50 }, styles.center]}>
      <TestBox gestureType={Gesture.Pan()} bgColor="#b58df1" />
      <TestBox gestureType={Gesture.LongPress()} bgColor="#f1a85d" />
      <TestBox gestureType={Gesture.Fling()} bgColor="#5df1a8" />
      <TestBox gestureType={Gesture.Tap()} bgColor="#5d8ef1" />
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  center: {
    display: 'flex',
    justifyContent: 'space-around',
    alignItems: 'center',
  },
  box: {
    height: 100,
    width: 100,
    backgroundColor: '#b58df1',
    borderRadius: 20,
    marginBottom: 30,
  },
});

@m-bert m-bert requested a review from j-piasecki October 20, 2025 10:03
…ndler.m

Co-authored-by: Jakub Piasecki <jakub.piasecki@swmansion.com>
@m-bert m-bert merged commit ec656ba into main Oct 20, 2025
4 checks passed
@m-bert m-bert deleted the @mbert/fix-double-tap branch October 20, 2025 15:20
j-piasecki added a commit that referenced this pull request Oct 27, 2025
## Description

Some changes in #3740 required follow up.

#### Tap

Turns out that we can leave `triggerAction` in `reset` (thank you apple
for transparent docs that clearly describe what changed between 18.5 and
26 ❤️).

It also seems that double `onFinalize` issue is fixed on 26.

#### Fling

Removing `[self triggerAction]` from `reset` broke things on old iOS.
Unfortunately now swiping in different direction does not result in
calling `onFinalize` - this should be handled by `triggerAction` in
`reset`, but now by default recognizers in `reset` have `Possible` state
(once again, thank you apple 😄). To fix that we will probably have to
rewrite fling to custom logic.

#### LongPress

`LongPress` was missing on `triggerAction` call that sends `fail`.

#### Pan 

In `Pan`, I've moved `triggerAction` calls from `touches*` methods to
`interactions*` methods.


## Test plan

<details>
<summary>Tested on basic-example and the following code:</summary>

```tsx
import { StyleSheet, View, Text } from 'react-native';

import {
  GestureHandlerRootView,
  Gesture,
  GestureDetector,
  GestureType,
} from 'react-native-gesture-handler';

function TestBox({
  gestureType,
  bgColor,
}: {
  gestureType: GestureType;
  bgColor: string;
}) {
  const handlerName = gestureType.handlerName;

  const gesture = gestureType
    .onBegin(() => {
      console.log(`[${handlerName}] onBegin`);
    })
    .onEnd(() => {
      console.log(`[${handlerName}] onEnd`);
    })
    .onFinalize(() => {
      console.log(`[${handlerName}] onFinalize`);
    })
    .runOnJS(true);

  return (
    <View style={styles.center}>
      <Text>{handlerName}</Text>
      <GestureDetector gesture={gesture}>
        <View style={[styles.box, { backgroundColor: bgColor }]} />
      </GestureDetector>
    </View>
  );
}

export default function App() {
  return (
    <GestureHandlerRootView style={[{ flex: 1, padding: 50 }, styles.center]}>
      <TestBox gestureType={Gesture.Pan()} bgColor="#b58df1" />
      <TestBox gestureType={Gesture.LongPress()} bgColor="#f1a85d" />
      <TestBox gestureType={Gesture.Fling()} bgColor="#5df1a8" />
      <TestBox gestureType={Gesture.Tap()} bgColor="#5d8ef1" />
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  center: {
    display: 'flex',
    justifyContent: 'space-around',
    alignItems: 'center',
  },
  box: {
    height: 100,
    width: 100,
    backgroundColor: '#b58df1',
    borderRadius: 20,
    marginBottom: 30,
  },
});
```

</details>

---------

Co-authored-by: Jakub Piasecki <jakub.piasecki@swmansion.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants