У меня есть UITableView
, который подвергается пакетному обновлению при изменении состояния приложения. Изменение может повлиять на несколько строк/разделов или только на один раздел (но на 1 или более строк).
Я заметил, что при обновлении одного раздела (которое может повлиять на ряд строк в разделе) заголовки разделов для других разделов отскакивают или перемещаются из своей предыдущей позиции, а затем анимируются обратно на место.
Картинка рисует тысячу слов...
Эти разделы не являются частью пакетного обновления.
UITableView
/Controller
настраивается с помощью раскадровки, предназначенной для iOS 11. UITableView
использует расчетную высоту строк и секций, а ячейки размещаются с использованием автоматического макета.
UITableViewController
использует более крупную модель данных, которая управляет операциями состояния и изменения состояния. API гарантирует, что требуемые обновления рассчитываются на основе требуемого состояния модели (т. е. удаления и обновления относятся к предыдущему состоянию, вставки относятся к новому состоянию).
Последним шагом является применение рассчитанных изменений к табличному представлению посредством процесса пакетного обновления...
tableView.beginUpdates()
// Calculate the rows/sections which need to be changed
if let ops = operation.sections[.delete], ops.count > 0 {
tableView.deleteSections(ops, with: deleteSectionAnimation)
}
if let ops = operation.sections[.update], ops.count > 0 {
tableView.reloadSections(ops, with: reloadSectionAnimation)
}
if let ops = operation.sections[.insert], ops.count > 0 {
tableView.insertSections(ops, with: insertSectionAnimation)
}
if let ops = operation.rows[.delete], ops.count > 0 {
tableView.deleteRows(at: ops, with: deleteRowAnimation)
}
if let ops = operation.rows[.update], ops.count > 0 {
tableView.reloadRows(at: ops, with: reloadRowAnimation)
}
if let ops = operation.rows[.insert], ops.count > 0 {
tableView.insertRows(at: ops, with: insertRowAnimation)
}
tableView.endUpdates()
tableView.reloadData()
tableView.layoutIfNeeded()
Свойства анимации строк и разделов (например, deleteSectionAnimation
) установлены на automatic
. Я попытался установить анимацию раздела на none
без каких-либо различий.
Я пытался удалить reloadData
и layoutIfNeeded
в различных комбинациях, и хотя они создают другие проблемы, они, похоже, не приближаются к решению этой проблемы.
Я заметил одну вещь: это происходит только тогда, когда обновления, происходящие с UITableView
, выполняются за пределами экрана.
Я потратил некоторое время, пытаясь найти решение проблемы (например, не звонить reloadData
), но не могу найти что-то, что работает.
Есть ли какое-то другое свойство, функция, на которую я должен обратить внимание, или порядок, в котором выполняются обновления, неверен?
Примечания
- Это статическая таблица, настроенная с помощью раскадровки.
- Строки и разделы добавляются/удаляются во время изменения состояния, что, по-видимому, вызывает проблемы/изменения в представлении прокрутки.
- Хотя отключение анимации (с помощью
UIView.setAnimationsEnabled
), кажется, решает проблему, это нежелательное решение, поскольку оно удаляет анимацию для всех обновлений (на экране или вне экрана). - Проблема возникает только тогда, когда представление прокрутки НЕ находится в верхней части представления, обновления/анимации, происходящие, когда представление таблицы прокручивается до самого верха, не вызывают проблем.
- Я пытался использовать
indexPathsForVisibleRows
, чтобы определить, происходят ли обновления на экране или за его пределами, и отключить анимацию с помощьюUIView.setAnimationsEnabled
, но это не решает проблему, если обновление происходит на экране, а табличное представление не прокручивается вверх. просмотра прокрутки
UIView.setAnimationsEnabled
наfalse
? а затем установите его обратно в `true после того, как вы закончите обновление? В противном случае, если вы уже пробовали это, можете ли вы попробовать создать небольшой проект, который показывает эту проблему? - person TNguyen   schedule 08.11.2017UIView.setAnimationsEnabled
, хотя это и решает проблему, но, очевидно, останавливает все остальные анимации, которые я хочу. Я искал решение для использованияUIView.setAnimationsEnabled
, когда обновления находятся за пределами экрана, но поскольку управление состоянием безумно сложно, каждый раз, когда обновление также происходит в видимой области, когда табличное представление не находится в верхней части экрана. просмотр прокрутки, я получаю те же проблемы, что и описанные выше - person MadProgrammer   schedule 09.11.2017UIView.performWithoutAnimation
- person TNguyen   schedule 09.11.2017setAnimationEnabled
. К сожалению, отключить анимацию на самом деле невозможно (поскольку они мне нужны, когда на экране появляются обновления). Я реализовал версию этого решения, и оно решена проблема с подпрыгиванием прокрутки во время обновлений, но заголовки разделов по-прежнему подпрыгивают/двигаются - person MadProgrammer   schedule 09.11.2017