With the intention to obtain this, we have to hold observe of each the previous information supply and its index paths, in addition to the brand new information supply and its index paths. Observe that the index paths of the operations should not overlap with one another.
@objc func performBatchUpdates() {
// Assemble new information supply
let newData = serviceData[1].map { PostCell.Mannequin(num: $0)}
var tmpDataSource = dataSource
tmpDataSource.removeLast()
tmpDataSource.removeLast()
let newOrder = newData + tmpDataSource.filter { !newData.comprises($0) }
// Calculate take away indexes relative to previous indexes.
// Calculate insert indexes relative to new indexes.
// Calculate transfer indexes relative to each.
var deleteIndexes = [IndexPath]()
var insertIndexes = [IndexPath]()
var strikes = [(from: IndexPath, to: IndexPath)]()
var oldPostToIndex = [PostCellModel: Int]()
for (i, submit) in dataSource.enumerated() {
oldPostToIndex[post] = i
}
var newPostToIndex = [PostCellModel: Int]()
for (i, submit) in newOrder.enumerated() {
newPostToIndex[post] = i
}
for (submit, i) in oldPostToIndex {
if newPostToIndex[post] == nil {
deleteIndexes.append(IndexPath(row: i, part: 0))
}
}
for (submit, newIndex) in newPostToIndex {
if let oldIndex = oldPostToIndex[post] {
if oldIndex != newIndex {
strikes.append((from: IndexPath(row: oldIndex, part: 0), to: IndexPath(row: newIndex, part: 0)))
}
} else {
insertIndexes.append(IndexPath(row: newIndex, part: 0))
}
}
// Replace the ultimate dataSource
dataSource = newOrder
// Step 3: Carry out batch updates
tableView.performBatchUpdates {
tableView.deleteRows(at: deleteIndexes, with: .automated)
tableView.insertRows(at: insertIndexes, with: .automated)
for transfer in strikes {
tableView.moveRow(at: transfer.from, to: transfer.to)
}
}