How to add swipe actions to Collection View

With the Compositional Layout list configuration this is fairly easy.

Published: July 5, 2022
App Store

One of the reasons you might not want to replace your Table Views with Collection Views might be that the former has excellent support for swipe actions that are pretty common in iOS. They are frequently used for deleting items or perhaps favoriting them.

With the list layout configuration that Apple added to Compositional Layout with iOS 14, we can easily create swipe actions for Collection Views as well.

I have covered the basics of the list layout in previous post.

Adding leading and trailing swipe actions

Since the setup is the same for the leading and trailing actions, I will show how to set up the trailing ones.

Swipe actions are added via the UICollectionLayoutListConfiguration. We need to setup trailingSwipeActionsConfigurationProvider for the trailing actions.

This is a typealias for method or closure that takes IndexPath as the parameter and returns UISwipeActionsConfiguration. This is the collection of items we want to make available on swipe.

Let’s start with basic example:

config.trailingSwipeActionsConfigurationProvider = { [unowned self] indexPath in

    let favoriteAction = UIContextualAction(style: .normal, title: "Favorite") { action, sourceView, actionPerformed in
        // custom favorite action here
        actionPerformed(true)
    }
    return .init(actions: [favoriteAction])
}

This defines an action to favorite item, which will be available when the user swipes on the collection view cell.

If you couldn’t perform the action for some reason, you should return false via the actionPerformed callback.

Chances are, you want to act on the item that is displayed in the cell. For this we can ask our Diffable data source:

let favoriteAction = UIContextualAction(style: .normal, title: "Favorite") { action, sourceView, actionPerformed in
    if let item = self.datasource.itemIdentifier(for: indexPath) {
        // act on the item
    }

    actionPerformed(true)
 }

If you wanted to have leading swipe actions instead (or both), you would also configure the leadingSwipeActionsConfigurationProvider on the same list configuration.

Customizing the swipe actions

Chances are you want a custom background color for the swipe actions or perhaps an image instead of a title.

This can be easily customized once the action is created like this:

favoriteAction.backgroundColor = .systemYellow
favoriteAction.image = UIImage(systemName: "star")

And of course, there is the .destructive style available as well:

UIContextualAction(style: .destructive, title: "Delete")

You can also customize if a user should be able to complete the swipe action via swipe. This is configured on the UISwipeActionsConfiguration via property performsFirstActionWithFullSwipe. It defaults to true.

let swipeConfiguration = UISwipeActionsConfiguration(actions: [favoriteAction])
swipeConfiguration.performsFirstActionWithFullSwipe = false

Disabling swipe actions for specific rows

If you want to show swipe actions only for some rows, you can return nil from the provider implementation based on the indexPath.

config.trailingSwipeActionsConfigurationProvider = { [unowned self] indexPath in
    if indexPath.item == 0 {
        return nil
    }

    // rest of the code

This code will disable swipe actions for the first item in each section.

Bluesky logo

Follow on Bluesky to not miss new posts

Filip Němeček profile photo

WRITTEN BY

Filip Němeček Mastodon

iOS blogger and developer with interest in Python/Django.

iOS blogger and developer with interest in Python/Django.