In this tutorial I will explain how to implement a UI element popular on iOS devices - swipeable row with actions. We will use the react-native-gesture-handler
library.
Let's look at a singular row component:
<View style={styles.container}>
<TouchableOpacity style={styles.cardContainer} activeOpacity={1}>
<Image
source={{
uri: product?.images?.length
? product.images[0]
: settings.PRODUCT_IMAGE_PLACEHOLDER,
}}
style={styles.imageMini}
/>
<View style={styles.rightSide}>
<Text style={styles.title} numberOfLines={2}>
{product.title}
</Text>
<View style={styles.buttonAndPriceContainer}>
<MiniProductButton
quantity={
product.inCartCount ? (product.inCartCount as number) : 0
}
onPressAdd={() => {}}
onPressRemove={() => {}}
/>
<Text style={styles.priceText} numberOfLines={1}>
{formatPrice(product)}
</Text>
</View>
</View>
</TouchableOpacity>
</View>
The view should have a background color (or obscure the background in some other way), otherwise left and right actions will be visible on the screen the moment the user starts swiping!
container: {
alignSelf: 'stretch',
padding: 12,
flex: 1,
backgroundColor: palette.screenBackground,
},
First, we need to wrap this view in <Swipeable>
.
Then, we need to create a function that will return a view that will be rendered when the user swipes to the left.
const renderRightActions = () => {
return (
<View style={styles.rightActions}>
<TouchableOpacity
style={styles.favoriteButton}
onPress={onFavoritePressed}>
<IconFavoriteBig />
<Text style={styles.textInSwipe}>Favorite</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.deleteButton}
onPress={onDeleteItemPressed}>
<IconDelete />
<Text style={styles.textInSwipe}>Remove</Text>
</TouchableOpacity>
</View>
);
};
Now, we need to pass this function to <Swipeable>
as renderRightActions
prop. The complete code of the component:
return (
<Swipeable renderRightActions={renderRightActions}>
<View style={styles.container}>
<TouchableOpacity style={styles.cardContainer} activeOpacity={1}>
<Image
source={{
uri: product?.images?.length
? product.images[0]
: settings.PRODUCT_IMAGE_PLACEHOLDER,
}}
style={styles.imageMini}
/>
<View style={styles.rightSide}>
<Text style={styles.title} numberOfLines={2}>
{product.title}
</Text>
<View style={styles.buttonAndPriceContainer}>
<MiniProductButton
quantity={
product.inCartCount ? (product.inCartCount as number) : 0
}
onPressAdd={() => {}}
onPressRemove={() => {}}
/>
<Text style={styles.priceText} numberOfLines={1}>
{formatPrice(product)}
</Text>
</View>
</View>
</TouchableOpacity>
</View>
</Swipeable>
This is it! The actions will appear after the user swipes the component:
You can create left actions in the same way and pass them as renderLeftActions
.
There are also some useful props and methods that you should check out, such as friction
or overshootLeft/Right
.
Information about all available props and methods can be found here.
If you have any suggestions on how to improve this article, I'd love to hear them in the comments!
Top comments (0)