#ios #swift #uitableview #tableview #delete-row
#iOS #swift #uitableview #просмотр таблицы #удалить строку
Вопрос:
Я реализовал следующий механизм удаления: при удалении действия TableView удаляет выбранные строки, и если в разделе нет строк, он будет удален.
Мой механизм выглядит следующим образом:
guard let selectedRows = self.tableView.indexPathsForSelectedRows,
let indexPath = self.tableView.indexPathForSelectedRow else { return }
self.tableView.beginUpdates()
self.dataSource[indexPath.section].rows.remove(at: indexPath.item)
if self.dataSource[indexPath.section].rows.isEmpty {
self.dataSource.remove(at: indexPath.item)
self.tableView.deleteSections(IndexSet(arrayLiteral: indexPath.section), with: .fade)
}
self.tableView.deleteRows(at: selectedRows, with: .fade)
self.tableView.endUpdates()
Мой объект источника данных:
struct DataSource {
var section:String
var rows:[Row]
}
struct Row {
var data:String
}
Проблема в том, что когда я выбираю более одной строки и пытаюсь удалить выбранные строки, я влюбляюсь в следующее сообщение:
Недопустимое обновление: недопустимое количество строк в разделе 0. Количество строк, содержащихся в существующем разделе после обновления (5), должно быть равно количеству строк, содержащихся в этом разделе до обновления (6), плюс или минус количество строк, вставленных или удаленных из этого раздела (0 вставлено, 2 удалены), и плюс или минус количество строк, перемещенных в этот раздел или из него (0 перемещено, 0 удалено).’
Пока я удаляю по одной строке, мой механизм работает нормально, как и ожидалось. Удаляет даже пустой раздел. Есть мысли, где я не прав? Большое спасибо.
Комментарии:
1. Насколько я вижу,
self.dataSource[indexPath.section].rows.remove(at: indexPath.item)
удаляет только один элемент массива.2. Как это сделать, зависит от вас.
indexPath
представляет собой массив выбранных индексов. developer.apple.com/documentation/foundation/indexpath3. Не используйте
self.
столько, если это не нужно. Это излишне снижает читаемость и добавляет дополнительную длину без особого усиления.4. Вы проверяете, пуст ли источник данных для данного раздела. Затем вы удаляете раздел из tableview. Но вы не подтверждаете, что раздел tableview пуст. Если TableView.deleteSections вызывается в непустом разделе, я подозреваю, что он удаляет строку, а затем раздел. Затем ваш код переходит в режим ожидания и вызывает TableView.deleteRows. Это может быть причиной удаления дубликатов.
5. @Bugrym Я вижу. Просто идея: переместите код в функцию и просто вызовите функцию следующим образом
self.doStuff()
. Это также может улучшить общую читаемость
Ответ №1:
Решение: просто добавьте инвертированный массив indexPath. let invertedIndexPathes = selectedRows.sorted(by: >)
Фиксированный механизм:
guard let selectedRows = self.tableView.indexPathsForSelectedRows,
let indexPath = self.tableView.indexPathForSelectedRow else { return }
let invertedIndexPathes = selectedRows.sorted(by: >)
self.tableView.beginUpdates()
for itemIndexPath in invertedIndexPathes {
self.dataSource[itemIndexPath.section].rows.remove(at: itemIndexPath.row)
self.tableView.deleteRows(at: [itemIndexPath], with: .fade)
self.tableView.reloadData()
}
if self.dataSource[indexPath.section].rows.isEmpty {
self.dataSource.remove(at: indexPath.item)
self.tableView.deleteSections(IndexSet(arrayLiteral: indexPath.section), with: .fade)
}
self.tableView.endUpdates()