I can achieve this when not using RxSwift by doing the following. It works great, plays needed animation on the row being removed and doesn't reload the whole table:
let item = self.dataSource[(indexPath as NSIndexPath).row]
self.dataSource.remove(at: (indexPath as NSIndexPath).row)
tableView.deleteRows(at: [indexPath], with: .right)
With RxSwift I'm binding data to the tableView by doing this and when I accept new array, it reloads the whole table and the remove animation is not played:
// ViewModel:
let items: BehaviorRelay<[Item]> = BehaviorRelay(value: [])
func removeItem(_ item: Item) {
var loadedItems = items.value
if let removeIndex = loadedItems.firstIndex(of: item) {
loadedItems.remove(at: removeIndex)
}
items.accept(loadedItems)
}
//ViewController:
viewModel.items
.bind(to: tableView.rx.items) { [weak self] (table, index, item) in
// Creating cell for the `item`....
return cell
}
.disposed(by: self.disposeBag)
How can I update the viewModel.item source to remove a single element and make sure that the remove animation is playing on the tableview?
There is a library called RxDataSources that implements this very thing. Or you can do it yourself if your needs are simple. Just implement the one required method.
Here's an example:
You would use this by simply binding with it, like this:
You would add/remove cells by emitting a new array on the
sourceobservable.Here is a complete example using RxDataSources if you choose to use it:
Note: in neither case do you need to store a property of the data source, the RxCocoa library will take care of that for you.