我有一个问题,使细胞崩溃动画看起来始终如一。
我的形象胜过千言万语。这是同一个表视图的两个GIF:
折叠对于单元格“6”非常有效,但对于“5”则不然。看起来整个UITableView内容在执行折叠动画之前会跳起来。
我没有使用UITableViewAutomaticDimension
用于UITableView的rowHeight
。相反,我通过tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath)
方法提供行高,并使用表格视图的beginUpdates
/ endUpdates
扩展/折叠单元格。正如您所看到的,我也使用tableView.scrollToRow(at: indexPath, at: .none, animated: true)
滚动到扩展行(但只有在扩展时,所以它可能无关紧要)。
UITableViewController的子类嵌入在具有大标题和搜索栏的UINavigationController中(此处不可见,因为内容向下滚动)。 UINavigationController嵌入在UITabBarController中。
这是相关的扩展/折叠部分。传递nil indexPath
参数时,已经展开的单元格将会崩溃。
func expandRow(at indexPath: IndexPath?) {
selectedIndexPath = indexPath
tableView.beginUpdates()
tableView.endUpdates()
if let ip = indexPath {
tableView.scrollToRow(at: ip, at: .none, animated: true)
}
}
此方法计算行高,并由tableView(_:heightForRowAt:)
和tableView(_:estimatedHeightForRowAt:)
调用:
private func heightForRow(at indexPath: IndexPath) -> CGFloat {
var height: CGFloat
if selectedIndexPath == indexPath {
// Add some height variety
height = 300 + CGFloat((indexPath.row % 4) * 20)
} else {
height = 70
}
return height
}
这是GitHub回购:https://github.com/AleksanderMaj/CellCollapse
知道怎么改进吗?
此问题是维度敏感的(在具有不同屏幕大小的设备上执行相同步骤后,此问题可能无法重现)。这是在带有iOS 11.3的iPhone 7模拟器上录制的。
编辑1:保持自动滚动到扩展单元格非常重要。
您正在滚动到扩展行,这使得UITableView跳跃了一点。
所以这是一个重构的expandRow(at:)
方法:
func expandRow(at indexPath: IndexPath?) {
self.contentOffset = self.tableView.contentOffset
selectedIndexPath = indexPath
tableView.beginUpdates()
tableView.endUpdates()
if let contentOffset = self.contentOffset {
tableView.contentOffset = contentOffset
}
}
您还需要将var contentOffset: CGPoint?
属性添加到控制器。
更新我错了,你不需要把selectedIndexPath = indexPath
btw beginUpdates()
和endUpdates()
方法。更新了代码示例
如果在每行调整行高时调整此问题,请单击。与@Taras的答案几乎相同,虽然在这里,需要先删除动画,然后再分配保存的contentOffset。希望这可以帮助 :)
func expandRow() {
let savedContentOffset = tableView.contentOffset
tableView.beginUpdates()
tableView.endUpdates()
tableView.layer.removeAllAnimations()
tableView.setContentOffset(savedContentOffset, animated: false)
}
我有个主意。我不确定这个诀窍是否正常。
可折叠表具有以下功能:表格视图的高度在展开或折叠时会发生变化。
如果我们使用从UITableView继承的自定义视图,我们可以覆盖视图,contentSize和contentOffset的属性。通过覆盖这两个属性,我们可以使表视图停止,禁用滚动一段时间。
var contentSizeChanging: Bool = false
override var contentSize: CGSize {
willSet {
contentSizeChanging = true
}
didSet {
contentSizeChanging = false
}
}
override var contentOffset: CGPoint {
get {
return super.contentOffset
}
set(newValue) {
if contentSizeChanging { return }
super.contentOffset = newValue
}
}