9

we're in this situation where we use both react-native-gesture-handler Touchables AND react-native Touchables in our app. (By Touchables I mean TouchableOpacity, TouchableHighlight etc). As you know react-native-gesture-handler provides those components too so that they work when used as a child of a react-native-gesture-handler gesture recognizing component.

Initially

we thought we'd only use rn-gesture-handler Touchables in components that absolutely need rn-gesture-handler Touchables in order to work (i.e root views wrapped with a gestureHandlerRootHOC) and use rn Touchables everywhere else.

Unfortunately

we bumped onto cases where two of those components interfered, and we had weird issues (like touches going through a component as if it had pointerEvents="none" just because it used a rn touchable and not an rngh touchable in Android).

Possibly

A solution may be to replace EVERY single rn Touchable in our app with a rn-gesture-handler Touchable, but this is super hard because many of our dependencies are also using rn Touchables so it would be hard to replace all that - but also it would be even harder because rn-gesture-handler Touchables are NOT drop in replacements of rn Touchables and we've had issues styling rn-gesture-handler Touchables indeed.

Now what?

I need some help with solving that properly - even something hacky like a way to block touches going through react-native touchables would do I think.

Community
  • 1
  • 1
SudoPlz
  • 20,996
  • 12
  • 82
  • 123

1 Answers1

0

This is how I do it, first create a TouchablePlatform.ts file, then make use of it in your components. When passing withNativeResponder as a prop to the component, it will use those from react-native-gesture-handler.

// src/commons/components/TouchablePlatform.ts

import React, {FC} from 'react';
import {
  Platform,
  TouchableNativeFeedback,
  TouchableNativeFeedbackProps,
  TouchableHighlight,
  TouchableHighlightProps,
} from 'react-native';

import {
  TouchableNativeFeedback as TouchableNativeFeedbackGestureHandler,
  TouchableHighlight as TouchableHighlightGestureHandler,
} from 'react-native-gesture-handler';

export type TouchablePlatformProps = {withNativeResponder?: boolean} & (
  | TouchableHighlightProps
  | TouchableNativeFeedbackProps
);

export const TouchablePlatform: FC<TouchablePlatformProps> = ({
  children,
  withNativeResponder = false,
  style = {},
  ...props
}) => {
  if (withNativeResponder) {
    if (Platform.OS === 'ios') {
      return (
        <TouchableHighlightGestureHandler {...props} style={[{flex: 1}, style]}>
          {children}
        </TouchableHighlightGestureHandler>
      );
    }

    return (
      <TouchableNativeFeedbackGestureHandler
        {...props}
        style={[
          {
            flex: 1,
            maxWidth: '100%',
            width: '100%',
          },
          style,
        ]}>
        {children}
      </TouchableNativeFeedbackGestureHandler>
    );
  }

  if (Platform.OS === 'ios') {
    return (
      <TouchableHighlight {...props} style={[{flex: 1}, style]}>
        {children}
      </TouchableHighlight>
    );
  }

  return (
    <TouchableNativeFeedback {...props} style={style}>
      {children}
    </TouchableNativeFeedback>
  );
};
SkyzohKey
  • 755
  • 7
  • 16