software-mansion / react-native-gesture-handler

Declarative API exposing platform native touch and gesture system to React Native.
https://docs.swmansion.com/react-native-gesture-handler/
MIT License
6.13k stars 982 forks source link

Fix cancelling manual activation gestures blocking interactivity on iOS #3007

Closed latekvo closed 3 months ago

latekvo commented 4 months ago

Description

Having a gesture with manualActivation set to true freezes interactions globally when such gesture gets cancelled. If a touch or palm cancellation is triggered by the device, all touchable elements, both the native and the gesturized ones in the app become disabled. This state is fixed when the cancelled gesture is triggered again.

closes #2885

Test plan

Using the attached example on iOS iPad, perform the following sequence:

Code:

import React from 'react-native';
import { TouchableHighlight, View, Text, StyleSheet } from 'react-native';
import {
  Gesture,
  GestureHandlerRootView,
  GestureDetector,
} from 'react-native-gesture-handler';

export default function EmptyExample() {
  const pan = Gesture.Pinch()
    .manualActivation(true)
    .onTouchesDown((event) => {
      console.log('down', event);
    })
    .onTouchesCancelled((event) => {
      console.log('cancelled', event);
    })
    .onStart(() => console.log('started'));

  return (
    <GestureHandlerRootView style={exampleStyles.root}>
      <TouchableHighlight
        onPress={() => console.log(2)}
        underlayColor={'red'}
        style={[exampleStyles.button, { backgroundColor: '#21da1a' }]}>
        <Text>OUTSIDE DETECTOR</Text>
      </TouchableHighlight>
      <GestureDetector gesture={pan}>
        <View style={[exampleStyles.area, { backgroundColor: '#5e5e5e' }]}>
          <TouchableHighlight
            onPress={() => console.log(1)}
            underlayColor={'red'}
            style={[exampleStyles.button, { backgroundColor: '#dad41a' }]}>
            <Text>INSIDE DETECTOR</Text>
          </TouchableHighlight>
        </View>
      </GestureDetector>
    </GestureHandlerRootView>
  );
}

const exampleStyles = StyleSheet.create({
  root: {
    flex: 1,
  },
  area: { flex: 1, marginTop: 100 },
  button: {
    width: 100,
    height: 100,
    zIndex: 100,
    position: 'absolute',
  },
});