将行插入 UITableView 的顶部会导致行向下移动,从而导致动画效果不佳

Posted

技术标签:

【中文标题】将行插入 UITableView 的顶部会导致行向下移动,从而导致动画效果不佳【英文标题】:Inserting rows to the top of a UITableView causes the rows to shift down resulting in bad animation 【发布时间】:2018-04-24 18:01:46 【问题描述】:

我有一个应用程序,其行为类似于典型的消息传递应用程序。

假设用户有 100 条消息,我的页面大小为 20。当用户登陆页面时,我显示最后一页(消息从 80 到 100)。

当用户慢慢向上滚动时,当willDisplay 的 indexPath 变为indexPath.row = 0 && indexPath.section = 0 时,我会获取上一页 (60 - 80)。我构建数据源数组并调用insertRows:at:with:。我遇到的问题是,当我插入行时,它从indexPath.row = 0 && indexPath.section = 0 开始,这会导致它触发前一页的预取,从而导致对其余页面的过早预取。我可以设置一个标志来避免这种情况,但它仍然会向下推其余单元格,导致其松开滚动位置,然后返回导致动画闪烁。

我使用rowHeight = UITableViewAutomaticDimension 计算单元格高度。

我已经尝试过调用scrollToRow(at:at:animated),但在调用insertRows: 时它仍然下推。

我知道这在理论上是可行的,因为像 Whatsapp 和 iMessage 这样的应用程序具有这种行为(假设它们使用 tableView)并且它们运行良好。

这是我所拥有的要点:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    if !insertingRows && indexPath.section == 0 && indexPath.row == 0 
        loadData()
    


private func loadData() 
    dataSource.load( [weak self] (success: Bool, error: Error?) in
        guard let strongSelf = self else 
            return
        

        let newMessagesCount = 20 // testing
        var indices = [IndexPath]()
        for index in stride(from: 0, to: newMessagesCount, by: 1) 
            indices.append(IndexPath(row: index, section: 0))
        

        DispatchQueue.main.async 
            strongSelf.insertingRows = true
            UIView.setAnimationsEnabled(false)
            strongSelf.tableView.insertRows(at: indices, with: .none)
            UIView.setAnimationsEnabled(true)
            strongSelf.insertingRows = false
        
    )

【问题讨论】:

【参考方案1】:

您可以直接将元素添加到数据源,而不是使用 tableView 的插入行功能。然后,您可以将 DispatchQueue.main.async 函数中的代码替换为以下代码。

let oldContentHeight: CGFloat = tableView.contentSize.height
let oldOffsetY: CGFloat = tableView.contentOffset.y
tableView.reloadData()
let newContentHeight: CGFloat = tableView.contentSize.height
tableView.contentOffset.y = oldOffsetY + (newContentHeight - oldContentHeight)

有关更多信息,请参阅我找到的这个要点: https://gist.github.com/WorldDownTown/9ed681148e9224f7157c9e8620ce46b8

【讨论】:

以上是关于将行插入 UITableView 的顶部会导致行向下移动,从而导致动画效果不佳的主要内容,如果未能解决你的问题,请参考以下文章

将行插入 UItableView 错误

UITableView 在滚动时在顶部插入部分

使用 UINavigationController 时在 UITableView 顶部插入图像?

动画 UITableView 的自动布局顶部约束导致崩溃,有啥线索吗?

分组 UITableView 35 点/像素顶部插入/填充

向 uitableview 添加分隔符会导致布局约束错误