TableView willDisplayCell调用不在屏幕上的单元格(tableView分页)

ate*_*kov 7 pagination uitableview ios swift

我使用通过willDisplayCell(或cellForRowAt)进行自定义TableView分页的想法,并从服务器进行更新。

问题是,即使对于不在屏幕上的单元格,willDisplay也会调用。

仅当用户滚动到最后一个单元格时,如何处理此行为并更改流程以更新单元格?

private func isLoadingIndexPath(_ indexPath: IndexPath) -> Bool {
    return indexPath.row == self.orders.count - 1
}

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // fetch new data if user scroll to the last cell
    guard isLoadingIndexPath(indexPath) else { return }
    if self.totalItems > orders.count {
        fetchNextPage()
    }
}

private func fetchNextPage() {
    self.currentPage += 1
    self.delegate?.didReachLastCell(page: currentPage)
}
Run Code Online (Sandbox Code Playgroud)

didReachLastCell调用addOrders:

func addOrders(_ orders: [OrderView]) {
    self.orders.append(contentsOf: orders)
    reloadOrders()
}

fileprivate func reloadOrders() {
    self.tableView.reloadData()
}
Run Code Online (Sandbox Code Playgroud)

注意: cellForRowAt方法也可以重现相同的问题。

Muk*_*esh 15

我在UITableView.automaticDimension用于单元格高度时遇到了这个问题。我使用更高的estimatedRowHeight属性值解决了这个问题。

像这样的东西:

tableView.estimatedRowHeight = 1000
Run Code Online (Sandbox Code Playgroud)

现在willDisplay将只为可见的行调用。


小智 6

正如@iWheeBuy所说,willDisplayCell不会说该单元格在屏幕上,因此您可以通过检入tableView.visibleCells来实现。

但是,即使在滚动时调用此函数并将其显示在屏幕上,该函数tableView.visibleCells.contains(cell)也会为假。

对我有用的一种方法是延迟,因此完整代码为:(SWIFT 4)

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            if tableView.visibleCells.contains(cell) {
                // load more data
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)


iWh*_*Buy 3

来自有关以下内容的文档tableView(_:willDisplay:forRowAt:)

表视图在使用单元格绘制行之前将此消息发送给其委托,从而允许委托在显示单元格对象之前对其进行自定义。此方法使委托有机会覆盖表视图之前设置的基于状态的属性,例如选择和背景颜色。委托返回后,表视图仅设置 alpha 和框架属性,然后仅在滑入或滑出行时设置动画。

此描述没有提到仅针对屏幕上的单元格调用该方法。

您可以将分页逻辑放入其他一些方法中。例如:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    //
}
Run Code Online (Sandbox Code Playgroud)

并使用例如scrollView.contentOffsetscrollView.contentSize等检查表的状态tableView.indexPathsForVisibleRows...

  • 请注意,`scrollViewDidScroll` 被频繁调用,不要在那里放置繁重的逻辑。 (3认同)