У меня есть TableViewController со строками, содержащими задачи. Если у задачи есть атрибут task.done = 1, я хочу переместить его в конец таблицы.
Я не могу предоставить никакого кода, потому что не сомневаюсь, как это сделать.
Моя идея заключалась в tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) с использованием следующего кода:
let element = tasks.remove(at: indexPath.row)
tasks.insert(element, at: tasks.count)
Проблема в том, что это нужно сделать после загрузки таблицы, потому что, если первая строка - это, например, done = 1, она будет перемещена вниз и снова будет обработана в конце.
Никогда не изменяйте модель данных или таблицу в cellForRowAt.





Вы можете программно удалить строку из UITableView и программно вставить строку. Перед выполнением операций с UITableView убедитесь, что вы удалили / добавили определенный элемент в массив источника данных. В противном случае он просто рухнет.
Если вы хотите просто переместить строки, вы можете использовать приведенный ниже код. Это нужно сделать в том месте, где обновляется массив, содержащий источник данных.
tableView.moveRow(at: oldIndexPath, to: newIndexPath)
Если вы хотите удалить и вставить новые объекты в массив, вы можете попробовать метод, показанный ниже.
let element = tasks.remove(at: indexPath.row)
tableView.deleteRows(at: indexPath, with: .automatic)
tasks.insert(element, at: tasks.count)
tableView.insertRows(at: [IndexPath(row: tasks.count, section: 0)], with: .automatic)
Зачем вставлять и удалять? Используйте moveRow.
Спасибо. Мне больше нравится moveRow. Где мне это делать? внутри viewDidLoad()?
В определение выполненной задачи добавьте блок didSet. Вызывается после того, как все готово.
@rmaddy Согласен ..! Спасибо, что поправили меня. Обновил свой ответ.
Оберните свой код в блок beginUpdates-endUpdates. Используйте func moveRow (в indexPath: IndexPath, в newIndexPath: IndexPath)
Например: не проверено
self.tableView.beginUpdates()
let element = tasks.remove(at: indexPath.row)
let movingRowIndex = indexPath.row
tasks.insert(element, at: tasks.count)
let indexPath = NSIndexPath(forRow: movingRowIndex, inSection: 0)
var lastIndexPath = NSIndexPath(forRow:tasks.count, inSection: 0)
self.tableView.moveRow(at indexPath: IndexPath, to newIndexPath: lastIndexPath)
self.tableView.endUpdates()
Это не компилируется, и begin-/endUpdates бесполезен для одной операции.
Разве это не должно быть в цикле for, который проверяет атрибут done?
Возможный дубликат Swift - изменение порядка ячеек UITableView