Implementing Swipe Actions for List Items in Mobile Apps
Swipe-to-delete in iOS Mail appeared in 2007 and remains one of most copied patterns. Sounds simple—until you build it correctly on both platforms simultaneously.
Native Implementation vs Custom
On iOS UITableView has built-in mechanism via UISwipeActionsConfiguration. Method tableView(_:trailingSwipeActionsConfigurationForRowAt:) returns configuration with UIContextualAction array. Each action has .normal or .destructive style (destructive auto-colors red and shows confirmation). leadingSwipeActionsConfigurationForRowAt for swipe right.
For UICollectionView swipe actions don't exist out of box—either use UICollectionViewListConfiguration (available iOS 14+) or implement via UILongPressGestureRecognizer + UIPanGestureRecognizer with custom threshold and velocity logic. UICollectionViewListConfiguration is preferred path for new apps.
In SwiftUI—swipeActions(edge:allowsFullSwipe:content:) modifier on List element. allowsFullSwipe: true allows full swipe for first action. Limitation: unavailable before iOS 15, targeting below requires fallback via UIViewRepresentable.
On Android native swipe-action component for RecyclerView doesn't exist. Standard approach—ItemTouchHelper with ItemTouchHelper.SimpleCallback implementation. Override onChildDraw() for drawing background and icons on swipe, onSwiped() for event handling. Important nuance: onChildDraw called every frame on movement—all drawing must be maximally cheap, Canvas operations without allocations.
With Jetpack Compose—compose-foundation library contains SwipeToDismiss from material3. For full-featured actions left and right—rememberSwipeToDismissBoxState() and SwipeToDismissBox. Animation built on Animatable + LaunchedEffect.
Where Developers Lose Time
Main problem—cell state after swipe on reuse. In UITableView on dequeueReusableCell, cell returned to original position automatically. But if you make custom swipe via gesture recognizer—transform and alpha must reset in prepareForReuse(). Forgot—ghost artifacts appear in cells after scroll.
Android with ItemTouchHelper same story: after notifyItemRemoved() indices shift, and if you don't recalculate position in callback—wrong item deleted. Plus cancel swipe animation looks wooden without getAnimationDuration() customization.
Another scenario—conflict with horizontal scroll-container inside cell. UIScrollView and UITableView have competing gesture recognizers. Solved via gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) with priority logic by velocity direction at gesture start.
What's Included
Implement swipe actions for UITableView / UICollectionView / SwiftUI List on iOS and RecyclerView / Compose on Android. For Flutter—flutter_slidable with ActionPane support both sides. For React Native—react-native-gesture-handler with Swipeable component based on Reanimated 2.
Cover edge cases: gesture conflicts, state on reuse, haptic on destructive action, accessibility (VoiceOver/TalkBack should vocalize available actions via accessibilityCustomActions).
Timeline: 1 day—standard swipe actions on one platform. 2–3 days—cross-platform implementation with custom animations and full edge case coverage.







