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.12k stars 979 forks source link

onPress on a Text inside a PanGestureHandler #867

Closed Fantasim closed 11 months ago

Fantasim commented 4 years ago

Hi,

I have something like that

<PanGestureHandler>
<Text>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has 
been the industry's standard dummy text ever since the 1500s, when an unknown printer took 
a galley, visit my site <Text onPress={this._handlePressURL} >https://www.google.com</Text>
</Text>
</PanGestureHandler>

This issue is about this line <Text onPress={this._handlePressURL} >https://www.google.com</Text>

I'm implementing something similar to react-native-parsed-text which is about parsing a text, detecting links and transforming them into a pressable text.

Obviously since Text is not supported by react-native-gesture-handler the onPress event is not triggered.

Did someone already faced this problem, how did you do to solve it ?

Thank you

djorkaeffalexandre commented 4 years ago

Hello @Fantasim, any news?

Fantasim commented 4 years ago

Hi @djorkaeffalexandre , still not supported.

ankar84 commented 4 years ago

@Fantasim hello! Any updates about that issue? Thanks!

Ashoat commented 3 years ago

Figured I'd add – we recently observed that Text onPresss inside a GestureHandler work on iOS, but not on Android. This is on react-native-gesture-handler@1.10.3 and react-native@0.64.2.

@jakub-gonet, wondering if you have any context on this issue, and thoughts on how it could resolved or avoided.

Crashtor commented 3 years ago

While it works for iOS, I just noticed this is not just for <Text/>, but all onPress={}-events for elements such as <TouchableOpacity/> and <Pressable/> on Android.

jakub-gonet commented 3 years ago

I tried reproducing it without success. Looks like we have some difference between platforms on triggering gesture handler callbacks when triggering onTouch but that's a separate issue.

https://user-images.githubusercontent.com/12465392/129517380-62bde4e4-311f-428e-8262-d05cc4c4d937.mov

import * as React from 'react';
import { Platform, SafeAreaView, Text } from 'react-native';
import { PanGestureHandler } from 'react-native-gesture-handler';

function logWithPlatform(text) {
  console.log(`${Platform.OS}: ${text}`);
}

export default () => {
  return (
    <SafeAreaView style={styles.container}>
      <PanGestureHandler onBegan={() => logWithPlatform('pan onBegan')}>
        <Text>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur
          ultrices sagittis mi, eu porta mi tristique vitae. Fusce dolor mi,
          hendrerit a risus eget, facilisis faucibus velit. In pellentesque in
          sem a dapibus.
          <Text
            style={{ textDecorationLine: 'underline', color: 'seagreen' }}
            onPress={() => logWithPlatform('inner text onPress')}>
            Inner text
          </Text>
        </Text>
      </PanGestureHandler>
    </SafeAreaView>
  );
};

const styles = {
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    margin: 20,
  },
};

Could anyone share a repro example?

jakub-gonet commented 3 years ago

I also discovered that RN nested onTouch handlers don't work on Android. RN transforms nested text into flat SpannableString IIRC so this may be caused by that.

This is pure RN code, without any RNGH imports.

https://user-images.githubusercontent.com/12465392/129518285-c6909690-1a0d-4acb-9baf-8e12ad996560.mov

import * as React from 'react';
import { Platform, SafeAreaView, Text } from 'react-native';

function logWithPlatform(text) {
  console.log(`${Platform.OS}: ${text}`);
}

export default () => {
  return (
    <SafeAreaView style={styles.container}>
      <Text onPress={() => logWithPlatform('outer text onPress')}>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur
        ultrices sagittis mi, eu porta mi tristique vitae. Fusce dolor mi,
        hendrerit a risus eget, facilisis faucibus velit. In pellentesque in sem
        a dapibus.
        <Text
          style={{ textDecorationLine: 'underline', color: 'seagreen' }}
          onPress={() => logWithPlatform('inner text onPress')}>
          Inner text
        </Text>
      </Text>
    </SafeAreaView>
  );
};

const styles = {
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    margin: 20,
  },
};

Also, both snippets were tested on the newest master version of the example app (a5e9dc2).

LivingInLimbo commented 2 years ago

Having this problem now - was there ever a solution?

j-piasecki commented 11 months ago

I'm not exactly sure how this relates to Gesture Handler, onPress is a built-in React Native prop.

If it's about attaching gestures to nested Text components, I'm not sure that's easily doable since, as Jakub mentioned above, Android flattens the nested texts, so only one native view exists there.

diegolmello commented 11 months ago

@j-piasecki Imagine WhatsApp, Telegram or any messaging app with horizontal swipe actions (think of reply, delete, fav, etc). We need RNGH for that. Now imagine you have a message with a hyperlink, like: "onPress is a built-in React Native prop". This is a very common UX on any messaging app or social network.

RNGH prevents the onPress from working, so currently we need to choose between having gestures or having messages with onPress.

j-piasecki commented 11 months ago

I really don't see it. I've just tried to reproduce it, and on both platforms, the onPress gets triggered despite having a Pan gesture attached. Even the nested texts onPress which didn't work for Jakub above seem to work now:

https://github.com/software-mansion/react-native-gesture-handler/assets/21055725/b337265f-eb24-4663-9655-55646a782657

This is the code I've tried ```jsx import React from 'react'; import { Text, StyleSheet, View } from 'react-native'; import { GestureHandlerRootView, GestureDetector, Gesture, } from 'react-native-gesture-handler'; export default () => { const panGesture = Gesture.Pan() .onBegin(() => { console.log('panGesture onBegin'); }) .onStart(() => { console.log('panGesture onStart'); }) .onEnd(() => { console.log('panGesture onEnd'); }) .onFinalize((_e, success) => { console.log('panGesture onFinalize', success); }); return ( console.log('text press')}> Some text console.log('nested text press')}> Some nested text ); }; const styles = StyleSheet.create({ screen: { flex: 1, rowGap: 16, padding: 16, backgroundColor: 'whitesmoke', }, card: { rowGap: 16, padding: 16, borderRadius: 8, backgroundColor: 'white', flex: 1, justifyContent: 'center', alignItems: 'center', }, }); ```

If you're facing a problem related to this issue, please post a minimal reproduction.

diegolmello commented 11 months ago

We tried this in 2020 and tracked the comments on this issue. When I saw it closed with this comment being the last one, I had to comment in hope to reopen it. Maybe it was fixed after Feb 2022? Not sure when GestureDetector was released.

j-piasecki commented 11 months ago

We tried this https://github.com/software-mansion/react-native-gesture-handler/issues/867#issuecomment-579426703 and tracked the comments on this issue. When I saw it closed with https://github.com/software-mansion/react-native-gesture-handler/issues/867#issuecomment-1043910527 being the last one, I had to comment in hope to reopen it.

If it's still affecting you, then please prepare a reproducible example. I cannot help much without it, as I cannot reproduce the issue (and neither could Jakub over 2 years ago).

Not sure when GestureDetector was released.

It was released in December of 2021

diegolmello commented 11 months ago

@j-piasecki

If it's still affecting you, then please prepare a reproducible example. I cannot help much without it, as I cannot reproduce the issue (https://github.com/software-mansion/react-native-gesture-handler/issues/867#issuecomment-899247840).

No worries. As I said, we had to make a choice and so we're not using gestures on messages. I'm going to create an internal task to try this in the future. Thanks, Jakub! :)