React Native Swipeable (Swipe to delete) not closing
Asked Answered
L

5

17

I'm using Swipeable from React-Native-Gesture-Handler to incorporate swipe to delete on my page. When I press delete, the contact gets deleted however the swipeable remains open.

I want it to close after it gets pressed but I can't seem to figure out how to do it.

This is my code:

const RightActions = (progress, dragX) => { 
return (
<TouchableOpacity onPress={()=>{DeleteContact(i)}}>
  <View style={[ContactsStyles.rightAction]}>
    <Text style={ContactsStyles.actionText}>Delete</Text>
  </View>
</TouchableOpacity>
) 
}

Here is where I have Swipeable:

<Swipeable renderRightActions={RightActions} >

     <View style={ContactsStyles.UserContainer}>

         <Text numberOfLines={1} style={[Fonts.Name]}> {obj.firstname} {obj.lastname} </Text>


         {/* Message/Call Container */}
          <View style={ContactsStyles.ImageCont}>
                    {/* Message */}
                    <TouchableOpacity onPress={()  => Communications.text(obj.phone, 'Hey ' + obj.firstname + ', im in need of a Ryde. Are you able to pick me up? This is my current location: ' + location)} >
                      <View style={ContactsStyles.ImageBox}>
                        <Image style={ContactsStyles.Image} source={require('../../assets/icons/message.png')} />
                      </View>
                    </TouchableOpacity>

                    {/* Call */}
                    <TouchableOpacity onPress = {() => Communications.phonecall( obj.phone , true)}>
                      <View style={ContactsStyles.ImageBox}>
                        <Image style={ContactsStyles.Image} source={require('../../assets/icons/phone.png')} />
                      </View>
                    </TouchableOpacity>
                  </View>
                  {/* End of Message/Call Container */}
      </View>
</Swipeable>

Swipeable button doesnt disappear after on press

Liability answered 24/11, 2019 at 20:31 Comment(0)
J
20

You need to use a reference which has a close method on it.

First define a ref

const swipeableRef = useRef(null);

then assign it to Swipeable

<Swipeable
  ref={swipeableRef}
  renderLeftActions={renderLeftActions}
  onSwipeableLeftOpen={() => handleComplete(item)}
>
    ...
</Swipeable>

and then just call the close method

const closeSwipeable = () => {
  swipeableRef.current.close();
}

Note, for multiple Swipeables you should have multiple refs.

let row: Array<any> = [];
let prevOpenedRow;

renderItem ({ item, index }) {
  return (
    <Swipeable
      ref={ref => row[index] = ref}
      friction={2}
      leftThreshold={80}
      rightThreshold={40}
      renderRightActions={renderRightActions}
      containerStyle={style.swipeRowStyle}
      onSwipeableOpen={closeRow(index)}
      ...
    >
    ...
    </Swipeable>);
}

closeRow(index) {
  if (prevOpenedRow && prevOpenedRow !== row[index]) {
    prevOpenedRow.close();
  }
  prevOpenedRow = row[index];
}

Jesseniajessey answered 1/4, 2020 at 8:58 Comment(1)
This works but it shows the close animation on the next-listed element (which has now moved up into the deleted item's position)Destructor
D
8

It's an index issue . When we have our list keyed on index, and we remove one item (eg index=3), the next item (previously index=4) now adopts the earlier index. Swipeable gets confused by this.

The answer is to key the list on something other than index (eg a unique id).

Destructor answered 12/7, 2022 at 10:22 Comment(0)
G
1

I had the same problem. What I did to solve that was to set the state array (which is shown in a list) to [] first before deleting that particular item. It cleared-up the screen (including the action panel) and rendered new items.

A part of my code:

const [notes, setNotes] = useState([]);

<FlatList
        data={notes}
......

when a note was deleted, I did: setNotes([]) and then setNotes(newNotes)

Galilee answered 15/6, 2020 at 15:50 Comment(0)
K
0

The solution to problem is to create a reference so that the swipeable may return to its initial position.

For this, import useRef from React and initialze it to null:

const swipeableRef = useRef(null);

Now you have the initial reference and use this reference to close the swipeable when you do function execution. Pass this to

<Swipeable ref = {swipeableRef}>

Do the following:

function yourFunction() {
   swipeableRef.current.close();

// enter code here

}

This way the swipeable will close first and then the function execution will work.

Happy Coding!

Khalif answered 17/1 at 9:0 Comment(0)
J
0
 <Swipeable
          renderRightActions={() => renderRightActions(index)}
          key={index + Math.random()} // this is solve my problem
>  
       <View>
           <Text> swipe </Text>
       </View>
</Swipeable>
Janettejaneva answered 11/7 at 7:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.