重新加载UITableView时,节标题“反弹”

Mad*_*mer 5 uitableview batch-updates ios swift

UITableView当应用程序状态更改时,我有一个批处理更新。更改可以影响许多行/节,或者仅影响一个节(但是1或更多行)。

我注意到,在进行单个节更新时(这可能会影响该节中的许多行),其他节的节标题会从其先前位置“反弹”或“移动”,然后动画化回原位。

一幅画画了一千个字。

视频截取

这些部分不是批量更新的一部分。

UITableView/ Controller是通过一个故事板中定位iOS 11的设置UITableView是利用“估算”行和段的高度,将细胞使用自动布局布置。

Xcode故事板属性

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()
Run Code Online (Sandbox Code Playgroud)

行和节的动画属性(即deleteSectionAnimation)设置为automatic。我尝试将部分动画设置为none没有任何差异

我尝试过删除reloadDatalayoutIfNeeded的各种组合,虽然它们创建了其他问题,但它们似乎无法解决这个问题

我注意到的一件事是,这似乎仅UITableView在屏幕外进行的更新完成时才会发生

我花了一些时间试图找到解决问题的方法(例如不致电reloadData),但找不到有效的方法。

还有其他我应该查看的属性,功能吗?执行更新的顺序是否错误?

笔记

  • 这是通过情节提要板设置的“静态”表格
  • 在状态更改期间添加/删除了行和节,这似乎触发了滚动视图中的问题/更改
  • 禁用动画(使用UIView.setAnimationsEnabled)确实可以解决此问题,但这是不受欢迎的解决方案,因为它会删除所有更新的动画(屏幕上或屏幕外)
  • 仅当滚动视图不在视图顶部时才出现此问题,将表格视图一直滚动到顶部时发生的更新/动画没有问题
  • 我尝试使用indexPathsForVisibleRows来确定更新是在屏幕上还是在屏幕外进行,并使用禁用动画,UIView.setAnimationsEnabled但是如果更新是在屏幕上进行的,而表格视图未滚动到屏幕顶部,则动画不能解决问题。滚动视图