【问题标题】:Detect UITableViewCells that appear on the screen检测屏幕上出现的 UITableViewCells
【发布时间】:2020-08-08 11:12:06
【问题描述】:

当用户看到 UITableViewCell 时我需要发出请求,我使用了func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath),但是这个方法在每个 UITableViewCell 显示之前调用,但是当 UITableViewCell 出现在屏幕上时我需要一个委托。

【问题讨论】:

  • 我认为你可以使用 cell layoutSubviews 中的委托方法。
  • 不,layoutSubviews 在加载表格视图时调用每个单元格
  • 将在表格视图即将加载时为每个单元格调用。
  • 是这样的,但是好像随机运行,不分别调用
  • 单元格是否必须完全可见,或者如果单元格部分可见也可以?有两种方法可以同时实现。

标签: ios swift uitableview cell uiappearance


【解决方案1】:

您需要做的是通过实现scrollViewDidScroll(_:) 委托方法来检测何时发生滚动。当调用委托方法时,您可以通过检查tableView.indexPathsForVisibleRows 属性来确定哪些单元格可见。请注意,此属性返回完全可见和部分可见的所有单元格的 IndexPath。

假设您只关心完全可见的单元格,您可以检查每一行的框架以确定它是否实际上是完全可见的。

要确定哪些单元格是新可见的,您需要跟踪以前可见的单元格并比较两组。

一旦显示单元格,此代码就会通知您:

var previousVisiblePaths = Set<IndexPath>()

override func scrollViewDidScroll(_ scrollView: UIScrollView) {

    guard let visiblePaths = tableView.indexPathsForVisibleRows?.filter ({
        let rect = tableView.rectForRow(at: $0)
        return tableView.bounds.contains(rect)
    }).reduce(into: Set<IndexPath>(), { result, indexPath in
        result.insert(indexPath)
    }) else { return }

    let newVisiblePaths = visiblePaths.subtracting(previousVisiblePaths)

    if newVisiblePaths.count > 0 {
        print("Just displayed: \(newVisiblePaths)")
    }

    previousVisiblePaths = visiblePaths
}

【讨论】:

  • 如果用户不滚动视图,对于呈现的单元格应该做什么,这取决于用户滚动
  • 在 viewDidAppear() 或 viewDidLayoutSubviews() 处获取 tableView.indexPathsForVisibleRows
  • 我赞成这个答案,但我想要一个更好的解决方案,scrollViewDidScroll 将要求在表格视图中进行一点滚动,因此在此方法中过滤 indexPathsForVisibleRows 的成本很高。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多