Delay style display when using Pressable React Native component

2.3k Views Asked by At

I'm using the Pressable React Native component for items displayed in a FlatList. I want to be able to scroll back and forth through the list and have no feedback from the items, unless pressed for a a little while.

The onPress function invoked can easily be delayed with the onLongPress capability, however I also want to invoke an opacity over the item after it's been pressed for a little while, NOT during scrolling. There doesn't seem to be an easy way to do this. What I've tried so far without succes:

.........

const sleep = (milliseconds: any) => {
   return new Promise(resolve => setTimeout(resolve, milliseconds));
};

const display = (pressed: boolean) => {
   if (pressed) {
      sleep(3000).then(() => {
         return true;
      });
   }
   return false;
};

const ItemInList: FunctionComponent<ItemInListProps> = ({
   style,
   colors,
   title = '',
   text,
   subtext,
   children,
   onPress,
}) => {
   return (
      <Pressable
         onLongPress={onPress}
         delayLongPress={3000}
         style={({ pressed }) => [
            {
               opacity: display(pressed) ? 0.2 : 1,
            },
         ]}>
         <LinearGradient
            colors={colors || []}
            style={StyleSheet.flatten([styles.container, style])}>
            <View style={styles.titleContainer}>
               <Text style={styles.titleStyle}>{title}</Text>
            </View>
            <View style={subtext ? styles.subtextContainer : styles.textContainer}>
               <Text style={styles.textStyle}>{text}</Text>
            </View>
            {subtext && (
               <View style={styles.subtextContainer}>
                  <Text style={styles.subtextStyle}>{subtext}</Text>
               </View>
            )}
            {children}
         </LinearGradient>
      </Pressable>
   );
};

export default ItemInList;

This has no effect whatsoever, opacity is never displayed. Does anyone have a good idea about how to handle this?

Thanks.

2

There are 2 best solutions below

3
On

Can you try TouchableOpacity? it has props delayPressIn and many props u can try these

0
On

I'm pretty sure that when the OP has asked this question, there was no straightforward solution. Right now you can use the "unstable_pressDelay" provided prop to define a number of milliseconds to delay the pressable activation.

Example code:

  <Pressable
    unstable_pressDelay={5000}
    onPress={() => {
      setTimesPressed((current) => current + 1);
    }}
    style={({ pressed }) => [
      {
        backgroundColor: pressed
          ? 'rgb(210, 230, 255)'
          : 'white'
      },
      styles.wrapperCustom
    ]}>
    {({ pressed }) => (
      <Text style={styles.text}>
        {pressed ? 'Pressed!' : 'Press Me'}
      </Text>
    )}
  </Pressable>

Documentation: https://reactnative.dev/docs/pressable#unstable_pressdelay