How to add custom swipe actions to a UICollectionViewListCell?
Published on: June 24, 2020In iOS 14 Apple added the ability for developers to create collection views that look and feel like table views, except they are far, far more powerful. To do this, Apple introduced a new UICollectionViewCell
subclass called UICollectionViewListCell
. This new cell class allows us to implement several tableviewcell-like principles, including swipe actions.
You can add both leading and trailing swipe actions to a cell by assigning a UISwipeActionsConfigurationProvider
instance to the collection view's UICollectionLayoutListConfiguration
object's leadingSwipeActionsConfigurationProvider
and trailingSwipeActionsConfigurationProvider
properties. This swipe actions provider is expected to return an instance of UISwipeActionsConfiguration
. A UISwipeActionsConfiguration
is created using an array of one or more UIContextualAction
instances.
You can customize the icon, title, and background color of a contextual icon as needed. Setting an image and background is optional but you are required to pass a title to the UIContextualAction
initializer.
Let's look at an example of how you can add a simple trailing swipe action to a list configuration instance:
let listConfig = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
listConfig.trailingSwipeActionsConfigurationProvider = { [weak self] indexPath in
guard let self = self else { return nil }
let model = self.dataSource[indexPath.row] // get the model for the given index path from your data source
let actionHandler: UIContextualAction.Handler = { action, view, completion in
model.isDone = true
completion(true)
self.collectionView.reloadItems(at: [indexPath])
}
let action = UIContextualAction(style: .normal, title: "Done!", handler: actionHandler)
action.image = UIImage(systemName: "checkmark")
action.backgroundColor = .systemGreen
return UISwipeActionsConfiguration(actions: [action])
}
let listLayout = UICollectionViewCompositionalLayout.list(using: listConfig)
collectionView = UICollectionView(frame: .zero, collectionViewLayout: listLayout)
This is a very simple configuration that adds a single trailing action to every cell in the list. The action is configured to have a green background and has a checkmark icon. Note that when you set an image on the action, the tite is hidden from view on iOS. It's still used for accessibillity so make sure to set a good title, even if you plan on using an image in the UI.
Important
Notice that I assignlistConfig.trailingSwipeActionsConfigurationProvider
before creating mylistLayout
property. SinceUICollectionLayoutListConfiguration
is astruct
you need to make sure it's fully configured before using it to create a list layout. If you create the list layout first, it will use its own copy of your list configuration and updates you make to your initial instance won't carry over to theUICollectionViewCompositionalLayout
because it uses its own copy of the configuration object.
You can return different configurations depending on the index path that you're supplying the swipe actions for. If you don't want to have any swipe actions for a certain index path, you can return nil
from the closure that's used to configure your swipe actions.
Note that I created a .normal
contextual action. The other option here is .desctructive
to indicate that an action might destruct data.
The action handler that's passed to UIContextualAction
receives a reference to the action that triggered it, the view that this occured in and a completion handler that you must call.
You also receive a completion handler in the action handler. You must call this handler when you're done handling the action and pass true
if you handled the action successfully. If you failed to successfully handle the action, you must pass false
. This allows the system to perform any tasks (if needed) related to whether you were able to handle the action or not.