Tap gesture with multiple pointers fail to start on `2.15.0`
levibuzolic opened this issue · 7 comments
Description
Upgrading from 2.14.1
to 2.15.0
has stopped tap gestures with minPointers(2)
from firing.
The tap gesture is setup as following:
const tap = Gesture.Tap()
.minPointers(2)
.runOnJS(true)
.onBegin((event) => {
console.log('onBegin', JSON.stringify({ event }));
})
.onStart((event) => {
console.log('onStart', JSON.stringify({ event }));
})
.onEnd((event, success) => {
console.log('onEnd', { event, success });
});
- On
2.15.0
onlyonBegin
fires, no other event is triggered. - On
2.14.1
all 3 events are triggered as expected. - Switching to
minPointers(1)
, the gesture works as expected
Minimal reproduction
import React, { useState } from 'react';
import { Text, StyleSheet, View, ScrollView, Button } from 'react-native';
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
export default function Home() {
const [log, setLog] = useState<string[]>([]);
const tap = Gesture.Tap()
.minPointers(1)
.runOnJS(true)
.onBegin((event) => {
setLog((prev) => [`onBegin: ${JSON.stringify({ event })}`, ...prev]);
})
.onStart((event) => {
setLog((prev) => [`onStart: ${JSON.stringify({ event })}`, ...prev]);
})
.onEnd((event, success) => {
setLog((prev) => [
`onEnd: ${JSON.stringify({ event, success })}`,
...prev,
]);
});
return (
<View style={styles.container}>
<GestureDetector gesture={tap}>
<View style={styles.container}>
<ScrollView>
<Button title="Reset" onPress={() => setLog([])} />
{log.map((line, i) => (
<Text key={i} style={[styles.log, i === 0 && styles.logNew]}>
{line}
</Text>
))}
</ScrollView>
</View>
</GestureDetector>
</View>
);
}
const styles = StyleSheet.create({
container: {
width: '100%',
height: '100%',
backgroundColor: 'white',
},
log: {
fontSize: 12,
color: 'grey',
padding: 5,
},
logNew: {
backgroundColor: '#e6ffec',
color: 'black',
},
});
Video
Kapture.2024-02-09.at.17.07.38.mp4
Steps to reproduce
- Set up a
Gesture.Tap()
with.minPointers(2)
- Perform a 2 pointer tap
onStart
andonEnd
are not fired
Snack or a link to a repository
https://github.com/software-mansion/react-native-gesture-handler
See the TwoPointerTap
example.
Gesture Handler version
2.15.0
React Native version
0.72.0
Platforms
iOS
JavaScript runtime
Hermes
Workflow
React Native (without Expo)
Architecture
Paper (Old Architecture)
Build type
Debug mode
Device
iOS simulator
Device model
No response
Acknowledgements
Yes
I'm in the process of looking through the diff between 2.14.1
and 2.15.0
to see if I can spot anything related.
Adding onFinalize
to the events, I can see that's getting called with success: false
.
const tap = Gesture.Tap()
.minPointers(2)
.runOnJS(true)
.onBegin((event) => {
setLog((prev) => [`onBegin: ${JSON.stringify({ event })}`, ...prev]);
})
.onStart((event) => {
setLog((prev) => [`onStart: ${JSON.stringify({ event })}`, ...prev]);
})
.onEnd((event, success) => {
setLog((prev) => [
`onEnd: ${JSON.stringify({ event, success })}`,
...prev,
]);
})
.onFinalize((event, success) => {
setLog((prev) => [
`onFinalize: ${JSON.stringify({ event, success })}`,
...prev,
]);
});
Looks like theres a bit of a diff in the tap handler for macOS support, is suepct it's something there but haven't found the smoking gun yet. 👀
Hi @levibuzolic! I will take a look at it and get back to you as soon as I find something!
Okay, I've found out what causes this problem. Before macOS support NSSet touches
contained UITouch
elements and calling count
resulted in getting actual amount of pointers. Now this set contains only one element and the real number of touches is hidden inside this element.
We will prepare a PR to fix that soon!
@m-bert awesome, thanks for looking into this! 🙇♂️