react-native-reanimated-bottom-sheet icon indicating copy to clipboard operation
react-native-reanimated-bottom-sheet copied to clipboard

Touchable Opacity inside renderContent has no actions when tapped on Android. iOS working fine.

Open roshangm1 opened this issue 5 years ago • 46 comments

Touchable Opacity inside renderContent has no actions when tapped on Android. iOS is working fine. It can be reproduced in this snack. (Took one of the snack from earlier issues) Long press the "Profile" tab to show the bottom sheet.

Inside bottom sheet, press click me text. https://snack.expo.io/@roshangm1/bottom-sheet

roshangm1 avatar Mar 24 '19 02:03 roshangm1

I see the problem. Gesture-handler ecosystem might not be consistent in some parts with RN gesture system. So I recommend using touchable from RNGH. However, they do not work on iOS (:cry:). As a temporary fix, you might use RNGH touchables on Android and RN touchables on iOS. It should not be like, but it's a problem in RNGH.

osdnk avatar Mar 24 '19 19:03 osdnk

Hmm cool. Tried the workaround and it's working. Hope your PR gets merged soon. In the meantime, do you think #15 is related ? Or were you even able to reproduce the issue ? @osdnk

roshangm1 avatar Mar 25 '19 00:03 roshangm1

I was able to repro, but I don’t have now a strong opinion

osdnk avatar Mar 25 '19 00:03 osdnk

is this fixed yet in the new release?

sudiddo avatar May 12 '19 05:05 sudiddo

same issues

zunsakai avatar Jun 14 '19 02:06 zunsakai

@osdnk Looks like the pull is ready, no? This blocks a lot of plans for our app, possible to merge?

JakeHadley avatar Jun 15 '19 01:06 JakeHadley

And react-native-gesture-handler not working on iOS, so we have to choose touchable dependent on OS

moxorama avatar Jun 20 '19 00:06 moxorama

Please fix this issue, we are waiting for fixes

aliwaqassi avatar Jul 30 '19 12:07 aliwaqassi

Sorry for not being very active. I’ll happily accept any PRs but now I’m truly overwhelmed by my job and react navigation stuff. Sorry I do my best, but I’m not any superhero :/

osdnk avatar Jul 30 '19 12:07 osdnk

@osdnk I think the big question is if this pull is what would fix this issue. If so, it's waiting to be reviewed/merged.

JakeHadley avatar Aug 07 '19 17:08 JakeHadley

If that helps you can do a custom component to fix it like this one:

import { TouchableOpacity as RNGHTouchableOpacity } from 'react-native-gesture-handler';

const BottomSheetTouchableWorkaround = ({
  children,
  onPress,
}: {
  children: ReactNode;
  onPress: () => void;
}) =>
  Platform.select({
    android: <RNGHTouchableOpacity onPress={onPress}>{children}</RNGHTouchableOpacity>,
    ios: (
      <TouchableOpacity onPress={onPress}>{children}</AppTouchableOpacity>
    ),
  });

slorber avatar Aug 21 '19 15:08 slorber

I face a little difference from this problem. I use FlatList, TextInput and TouchableOpacity from the Gesture Handler in BottomSheet. I use TextInput in the BottomSheet header to filter the data that will be created by FlatList. If TextInput never focuses when BottomSheet appears, BottomSheet can hide when I touch each item, or I can say, it can be programmatically hidden. But, once TextInput is focused, BottomSheet won't hide programmatically. IDK why this BottomSheet can not be hidden but the onPress function is executed properly. FYI, I put this.bottomSheet.current.snapTo (0) in the onPress function with the method for saving selected items.

I hope this problem will be resolved in the next release because my boss has asked when I can release this application.

Pholenk avatar Aug 30 '19 13:08 Pholenk

Might be resolved by the PR I just submitted: https://github.com/osdnk/react-native-reanimated-bottom-sheet/pull/85

rgoldiez avatar Sep 02 '19 13:09 rgoldiez

After a little rework of @slorber example I've got something like this. Works at least for iOS at the time and I will test it on android tomorrow.

import React, { memo } from "react";
import { Platform, TouchableOpacity } from "react-native";
import { TouchableOpacity as RNGHTouchableOpacity } from "react-native-gesture-handler";

const BottomSheetButton = ({ children, ...otherProps }) => {
  if (Platform.OS === "android") {
    return (
      <RNGHTouchableOpacity {...otherProps}>{children}</RNGHTouchableOpacity>
    );
  }

  return <TouchableOpacity {...otherProps}>{children}</TouchableOpacity>;
};

export default memo(BottomSheetButton);

Anyways,, hope that #85 get merge asap...

@osdnk

sebqq avatar Sep 08 '19 12:09 sebqq

@sebinq - were you able to try the PR I submitted? It’s working great for me (both iOS and Android) but your use case may be different.

rgoldiez avatar Sep 08 '19 12:09 rgoldiez

@rgoldiez i didn't right now I'm in busy but tomorrow maybe :)

sebqq avatar Sep 08 '19 12:09 sebqq

@rgoldiez same issue with the new prop enabledContentTapInteraction on Android

Under-Warz avatar Sep 10 '19 15:09 Under-Warz

@Under-Warz - just to make sure, did you set both enabledInnerScrolling and enabledContentTapInteraction to false?

rgoldiez avatar Sep 10 '19 16:09 rgoldiez

@Under-Warz - just to make sure, did you set both enabledInnerScrolling and enabledContentTapInteraction to false?

Set enabledInnerScrolling and enabledContentTapInteraction to false to make work with onPress()

dineshmm23 avatar Sep 26 '19 13:09 dineshmm23

here is the config I've made to make it work on both iOS and Android with button and horizontal drag slider

<BottomSheet
      enabledContentGestureInteraction={false}
      enabledInnerScrolling={false}
      enabledContentTapInteraction={false}
      snapPoints={[250, 50]}
      renderHeader={renderHeader}
      renderContent={renderContent}
      onCloseStart={handleCloseStarted}
    />

And the button inside the view use TouchableOpacity from RN for iOS and TouchableOpacity from react-native-gesture-handler for Android

Under-Warz avatar Sep 27 '19 09:09 Under-Warz

I need the internal scroll but with this configuration not working the scroll, works only onpress but the scroll does not, how does this project to operate the scroll and also the onpress https://market.nativebase.io/view/react-native-cryptostream-app-theme????????????'

dkpapo avatar Oct 07 '19 00:10 dkpapo

I need the internal scroll but with this configuration not working the scroll, works only onpress but the scroll does not, how does this project to operate the scroll and also the onpress https://market.nativebase.io/view/react-native-cryptostream-app-theme????????????'

i find a solution for me

<View style={styles.container}>
                <BottomSheet
                  ref={this.bs}
                  snapPoints={['85%', '51%']}
                  renderContent={this.renderInner}
                  renderHeader={this.renderHeader}
                  initialSnap={1}
                  enabledInnerScrolling={true}
                  enabledContentTapInteraction={false}

                />
                
              </View>

in renderinner

    <Animated.View style={styles.panel}>
      <View style={styles.align}>
        <Icon
          active
          type={'FontAwesome5'}
          name="directions"
          style={{ color: "red",right:'10%' }}
        />
        <Text style={styles.panelTitle}>{this.state.request.address_final}</Text>
      </View>
      <View style={styles.align}>
        <Icon
        active
        type={'MaterialIcons'}
        name="my-location"
        style={{ color: "blue",right:'10%' }}
        />
        <Text style={styles.panelSubtitle}>{this.state.request.direction}</Text>
      </View>
      <View
        style={{
          borderBottomColor: 'black',
          borderBottomWidth: 1,
        }}
      />
      <View style={styles.align}>
        <Text style={styles.titleText}>
          Presupuesto
        </Text>
        <Text style={{fontSize: 20, textAlign:'right',flex:1 }}>
          ${this.state.request.budget}
        </Text>
      </View>
      <View
        style={{
          borderBottomColor: 'black',
          borderBottomWidth: 1,
        }}
      />
      <View style={styles.align}>
        <Text style={styles.titleText}>
          Numero de pasajeros
        </Text>
        <Text style={{fontSize: 20, textAlign:'right',flex:1 }}>
          {this.state.request.number_users}
        </Text>
      </View>
      <View
        style={{
          borderBottomColor: 'black',
          borderBottomWidth: 1,
        }}
      />
      <View style={{flexDirection:'column',padding:10,}}>
        <Text style={{fontSize: 14,color: 'gray',marginBottom: 10}}>
          Datos adicionales
        </Text>
        
          
        <Text  style={{fontSize: 15}}>
          {this.state.request.description}
        </Text>

      </View>
      
      <Button 
        warning
        large
        rounded
        onPress={() => Alert.alert(
      '',
      'Esta seguro que desea cancelar el servicio?',
      [
        
        {text: 'Si', onPress: () => this.CancelService()},
        {text: 'No', onPress: () => null},
      ],
      {cancelable: true},
    )}>
        <Text>Cancelar</Text>
      </Button> 
    </Animated.View>

and important in style

panel: { // height: '100%', padding: 20, backgroundColor: 'white', },

dkpapo avatar Oct 07 '19 01:10 dkpapo

Hey

For what it's worth, here's the solution I've found to encapsulate the workaround:

export const AppBottomSheetTouchableWrapper = (
  props: { children: ReactNode } & Pick<
    TouchableWithoutFeedbackProps,
    'onPress' | 'disabled'
  >,
) =>
  Platform.select({
    android: <RNGHTouchableWithoutFeedback {...props} />,
    ios: (
      <TouchableWithoutFeedback {...props}>
        <View>
          <View pointerEvents="none">{props.children}</View>
        </View>
      </TouchableWithoutFeedback>
    ),
  });

And I have to wrap the existing touchable component (without providing it the onPress prop:)

      <AppBottomSheetTouchableWrapper onPress={onPress}>
        <AppButton>ButtonText</AppButton>
      </AppBottomSheetTouchableWrapper>

I'm happy with that as it seems to encapsulate the workaround with a common abstraction for both platforms

slorber avatar Oct 23 '19 16:10 slorber

Having the same issue, and I stumbled upon the same workaround on my own, however, this is not a perfect solution if one uses a UI library, (ex: react-native-paper) in my case, then the components stop working (ex: button) and there is not easy way to patch it, besides re-implementing the components using Touchables.

Just my 2 cents here, would like to know if/when this gets fixed.

ospfranco avatar Dec 11 '19 15:12 ospfranco

Does anyone have a workaround to make a <FlatList /> scrollable? I have used a combination of these workarounds within my app (we use lots of sheets with Touchbales in renderContent and renderHeader and FlastLists within renderContent) and none of the workarounds seem to allow scrolling within a <FlatList /> for Android only. iOS works great. Same goes for a WebView within renderContent

I have tried setting each enabledInnerScrolling={true/false} enabledContentTapInteraction={true/false} enabledGestureInteraction={true/false and it didn't seem to make a difference.

timothystewart6 avatar Jan 10 '20 19:01 timothystewart6

When I inspect there's a <BottomSheetBehavior /> blocking gestures above my components.

timothystewart6 avatar Jan 11 '20 00:01 timothystewart6

Have you tried using flatlist component from react native gesture package?

ospfranco avatar Jan 11 '20 08:01 ospfranco

@ospfranco I have, thank you. Unfortunately it's the same. I think it is stemming from having multiple sheets rendered at once and somehow it's pushing a BottomSheetBehavior up, even when all sheets are closed. This is my best guess so far. It's not consistent either, sometimes it's there, sometimes it's not.

timothystewart6 avatar Jan 13 '20 17:01 timothystewart6

Hey Guys. I too encountered the same issue. and I have tried an alternative solution and it worked for me and per my requirement. I just added an Alert on TouchableOpacity and on Alert OnPress handled the HideBottomSheet.

Alert.alert( 'Alert Title', 'My Alert Msg', [ { text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel', }, { text: 'OK', onPress: () => { this.bs.current.snapTo(0); } }, ], { cancelable: false }, );

Ratzz30 avatar Jan 16 '20 13:01 Ratzz30

One work around i found was to call snapTo twice.

<TouchableOpacity 
  onPress={() => {
    bottomSheetRef.current?.snapTo(0);
    bottomSheetRef.current?.snapTo(0);
  }}
>

safaiyeh avatar Jan 21 '20 00:01 safaiyeh