对使用自动布局的UITableView进行上拉加载更多操作时,tableView向上跳动一定的高度

问题:
对使用自动布局的UITableView进行上拉加载更多操作时,tableView向上跳动一定的高度。

分析:
搜索“UITableView 自动布局 加载数据 reloadData 跳动”之类的关键字,搜出来的是手动布局下设置estimatedRowHeight = 0;自动布局下在VC中增加一个字典来缓存indexPath对应的高度之类的答案。
成员变量

private var cellHeightsDictionary: [String: CGFloat] = [:]

willDisplay函数

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        cellHeightsDictionary["\(indexPath.section)"] = cell.frame.size.height
        "\(indexPath.section) \(cell.frame.size.height)".ext_debugPrint()
    }

estimatedHeightForRowAt函数

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        if let height = cellHeightsDictionary["\(indexPath.section)"] {
            "\(indexPath.section) \(height)".ext_debugPrint()
            return height
        } else {
            "\(indexPath.section) 100".ext_debugPrint()
            return 100//UITableView.automaticDimension
        }
    }

即使这样做,仍然有上拉加载后tableView向上跳动的问题。我将cell的内容减到最少只保留一个UILabel,仍然有问题。通过检查代码发现:在func scrollViewDidScroll(_ scrollView: UIScrollView)方法后会通知VC进行下面的操作:

UIView.animate(withDuration: self.keyboardView.keyboardTime, animations: {
    self.view.layoutIfNeeded()
    self.view.setNeedsLayout()
})

导致tableView进行了异常刷新。
解决:
1,去掉立刻刷新布局的代码后正常。
2,删除缓存预估高度的代码。因为estimatedHeight变量或者estimatedHeightForRowAt函数的作用只是为了调整UIScrollView指示条的高度。对于设定了self.tableView.rowHeight = UITableView.automaticDimension的tableView,会在显示cell前计算好cell的contentSize,无需缓存。

备忘:
分析过程中我还试图在reloadData后使用scrollTo的方法移动到最下方,但是在快速滑动上拉加载时,会有明显的下拉感。
另外,在自动布局的tableView中是不能读取/修改其contentOffset的,在文档中有明确的说明。

发布了74 篇原创文章 · 获赞 81 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/dangyalingengjia/article/details/105432913