Swift

Interact with TableView when using DiffableDataSource

In the first post we discussed on using DiffableDataSource and Combine together but so far we only learned how to setup data source. In this part we’re going to learn how to setup swipe to delete action by creating your own DiffableDataSource. If you haven’t read the first part you can find it here:

Swipe to interact with the table view

Also, you can download the starter project here:

https://github.com/LearnWithTung/DiffableCombine-part2/tree/master/starter

Subclassing DiffableDataSource

In order to create your own DiffableDataSource we need to inherit from UITableViewDiffableDataSource class. Add a new swift file bellow FeedViewController.swift file and name it CustomDataSource then add this code into this file:

// 1
class CustomDataSource<Section: Hashable, Cell: Hashable>: UITableViewDiffableDataSource<Section, Cell> {

}
  1. Define CustomDataSource which is a generic class requiring two types conforming to Hashable.

Move to FeedViewController, in order to using our custom class let’s replace:

    typealias DiffableDataSource = UITableViewDiffableDataSource<Int, User>

with:

    typealias DiffableDataSource = CustomDataSource<Int, User>

That’s… it. That’s all you need, let’s run the application. Nothing changes because we didn’t do anything much so far.

Swiping actions

So how do we make the table view interactive ? Well, it turns out very similar to how we do when using traditional way. First, let’s make CustomDataSource conform to UITableViewDelegate then add this code inside it.

    // 1
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    // 2
    func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let deleteAction = UIContextualAction(style: .destructive, title: "Delete") {  (contextualAction, view, boolValue) in
            self.deleteRow(at: indexPath)
        }

        let editAction = UIContextualAction(style: .normal, title: "Edit") {  (contextualAction, view, boolValue) in
            self.editRow(at: indexPath)
        }
        editAction.backgroundColor = .orange
        let swipeActions = UISwipeActionsConfiguration(actions: [deleteAction,editAction])

        return swipeActions
    }
    // 3
    func deleteRow(at indexPath: IndexPath) {
        // handle delete
    }
    // 4
    func editRow(at indexPath: IndexPath) {
        // handle editing 
    }
  1. By returns true we allow table view interactive.
  2. create two actions, one for delete and other for edit. Of course, you can create what ever you want.
  3. Delegate function for handle deletion.
  4. Delegate function for handle editing.

If you try to run our application. You almost get what we want, our table view now can swipe to interact but nothing else, to continue our job is implement the two delegate functions above.

There are many ways out there and all of them are valid but one of best way is using delegate pattern. So if you’re familiar with the pattern let’s try on your own otherwise read bellow to see how we can achieve it.

Define our protocol like this:

protocol DataSourceDeletionDelegate: class {
    func deleteRow(at indexPath: IndexPath)
}

Then at the very beginning of CustomDataSource, add this line:

weak var delegate: DataSourceDeletionDelegate?

And then to finish CustomDataSource implementation, inside deleteRow(at:) add this code:

delegate?.deleteRow(at: indexPath)

Done ! I’ll leave the rest delegate function for you.

Back to FeedViewController.swift add this two lines of code at the end of viewDidLoad:

        tableView.delegate = dataSource
        dataSource.delegate = self

You’ll get a compile error, it get rid of it, add this code at the end of the class:

extension FeedViewController: DataSourceDeletionDelegate {
    func deleteRow(at indexPath: IndexPath) {
        users.remove(at: indexPath.row)
    }
}

We don’t need to call reloadData() because the users property isn’t a normal variable but a publisher, if you can’t get it please read the part 1. And that’s really it. Run the application, you’ll see what we expected.

You can find the final project here:

https://github.com/LearnWithTung/DiffableCombine-part2/tree/master/final

Conclusion

Alright, it’s conclusion time. Thank you so much for reading, I hope you fully understand what’ve shown. Don’t forget to practice on your own and if you like this post please share if you have any question related feel free to comment down bellow.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *