Skip to content

When FlatList is inverted, tap gestures are not detected #60

@pafry7

Description

@pafry7

描述 / Description

When transform: [{scaleY: -1}] is applied to ScrollView, tap gestures failed to detect items due to incorrect transform composition and offset handling in hit-box calculation.

Minimal repro:

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

function GestureDetectorItem(props) {
  const logTap = Gesture.Tap().onStart(() => {
    console.log('onPress event logTap');
  });

  const logLongPressGesture = Gesture.LongPress().onStart(e => {
    console.log('onPress event logLongPressGesture', e);
  });
  const composed = Gesture.Simultaneous(logTap, logLongPressGesture);

  return (
    <GestureDetector gesture={composed}>
      <View
        style={{
          width: 100,
          height: 50,
          backgroundColor: 'skyblue',
          borderWidth: 1,
        }}/>
    </GestureDetector>
  );
}

export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1, margin: 50 }}>
      <View
        style={{
          flex: 1,
          transform: [{ scaleY: -1 }],
          gap: 20,
          borderWidth: 1,
        }}>
          <GestureDetectorItem />
      </View>
    </GestureHandlerRootView>
  );
}

Repro with the FlatList:

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

const FlatListExample = ({
  longPressGesture,
}: {
  longPressGesture: LongPressGesture;
}) => {
  const logTap = Gesture.Tap().onStart(e => {
    console.log('onPress event logTag: ', e);
  });

  const FlatListItem = ({firstItem}: {firstItem: boolean}) => {
    return (
      <GestureDetector gesture={Gesture.Simultaneous(logTap, longPressGesture)}>
        <View>
          <Text
            style={{
              width: 100,
              height: 50,
              backgroundColor: 'skyblue',
              marginBottom: 20,
            }}>
            {firstItem ? 'SCROLL TO THE TOP AND LONG PRESS' : 'PRESS ME'}
          </Text>
        </View>
      </GestureDetector>
    );
  };

  return (
    <GestureHandlerRootView style={{ flex: 1, margin: 50 }}>
      <FlatList
        inverted={true}
        data={Array.from({length: 10}, (_, i) => ({key: `${i + 1}`}))}
        renderItem={({item, index}) => (
          <FlatListItem key={item.key} firstItem={index === 0} />
        )}
      />
    </GestureHandlerRootView>
  );
};

复现步骤 / Steps to reproduce

No response

库版本 / Library version

2.14.17-rc.1

React Native OpenHarmony version

0.72.27, 0.77.11

构建类型 / Build type

None

设备 / Device

None

设备版本 / Device model

No response

已悉知 / Acknowledgements

Yes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions