检测UITableViewCell何时从屏幕上消失

klr1opcd  于 2022-09-19  发布在  Swift
关注(0)|答案(8)|浏览(291)

我正在用定制创建的UITableView实现一个丰富的UITableView,我以一种方式在屏幕上显示它们,但一旦它们离开屏幕,我想要注意这一点,因为它们第二次出现时,我希望它们以不同的方式显示。当从屏幕上消失时,想想自动“标记为已读”。

我一直在寻找某种方法来检测信元何时离开屏幕(GET的解除分配或出列或等效),最好是在UITableViewController类中快速记录indexPath.row值,但在UITableViewCell中也一样好。

我一直不能以任何标准的方式做到这一点。计算它出现的次数似乎是不可能的,因为我在表上进行了多次reloadData调用。

有谁有主意吗?这看起来有点棘手:)

aelbi1ox

aelbi1ox1#

这是一个古老的问题,但如果有人正在寻找,在iOS6中,引入了一个新的UITableViewDelegate函数,它就是这样做的:

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

无论何时一个单元格被移除,它都能很好地告诉你,然而,它是非常彻底的,因此,如果你重新加载单元格,即使是正在被替换的旧单元格也会触发这个委托函数。在我的实现中,我只需检查传递的indexPath是否仍在数组tableView.indexPathsForVisibleRows中。类似于:

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([tableView.indexPathsForVisibleRows indexOfObject:indexPath] == NSNotFound)
    {
        // This indeed is an indexPath no longer visible
        // Do something to this non-visible cell...
    }
}
lfapxunr

lfapxunr2#

我想你可以用这个

- (NSArray *)visibleCells

方法用于您的UITableView。这将返回一个包含所有可见单元格的数组。然后,您可以以您想要的方式标记任何“不可见”(即,不在此数组中)的数据,这样当您向后滚动到它时,它已被更新。

希望这能有所帮助

wmvff8tz

wmvff8tz3#

一旦UITableViewCell不可见,它将从UITableView中删除。您可以重写方法-(void)removeFromSuperView,并在该方法中执行某些操作。最后,不要忘记调用[super removeFromSuperView]

os8fio9y

os8fio9y4#

Andrey Tarantsov提到的UITableViewCell上的prepareForReuse方法看起来不错。在其中放入几个NSLogs允许您打印出单元格的任何变量的值。对于如何将其设置回表视图控制器,您有什么想法?

b4lqfgs4

b4lqfgs45#

你确定屏幕外的手机就是你想要捕捉到的吗?如果要将邮件标记为已读,这似乎不是正确的方法。例如,我可能会非常快地滚动表格,如果您将所有内容标记为已读,我会非常惊讶。

至于技术部分,只需保留屏幕上的单元格列表(cellForRowAtIndexPath应将单元格添加到该列表中),并在scrollViewDidScroll委托方法中检查是否有任何单元格不再可见。

另一个可能的想法是:我记得单元格上有prepareForReuse方法。不过,不确定什么时候会调用它。

hgqdbh6s

hgqdbh6s6#

我知道这是一个非常古老的问题,但如果有人在寻找斯威夫特5的答案:

func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    <#code#>
}
1wnzp6jl

1wnzp6jl7#

我想我会尝试定期检查UITableView的indexPathsForVisibleRow属性。从最大的索引路径中,您可以推断之前的所有行都已滚动过去。

0s0u357o

0s0u357o8#

当单元格滚动出屏幕时,我需要从单元格中获取一些数据。我使用了@T先生的答案,但它没有说明如何获取数据。

例如,假设我使用的单元格类的名称是MyCell,其中有一个名为MyModel的数据模型,其属性为postID。我最初在cellForItem中设置了该信息:

var datasource = [MyModel]()

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MyCell

    cell.myModel = datasource[indexPath.item] // an individual instance of MyModel from the array

    print("cellForItem - indexPath.item: ", indexPath.item) // if the was the very first cell coming on it would print 0
    print("postId: ", cell.myModel.postId) // maybe the postId is qwerty

    return
}

要从屏幕上滚动离开的单元格中获取一些数据:

func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {

    guard let myCell = cell as? MyCell else { return } // You must cast the cell from the method param to your cell type which for me is MyCell

    print("didEndDisplayingCell - indexPath.item: ", indexPath.item) // if this was the very first cell scrolling off it should print 0
    print("postId: ", myCell.myModel.postId) // the postId should be qwerty
}

测试这一点的最好方法是将少量的单元格添加到集合视图中,比如首先添加2个单元格,然后添加到3个单元格,然后添加到4个单元格。然后只需滚动第一个单元格,看看打印出了什么。对每个单元格执行此操作。对于cellForItemdidEndDisplaying,indexPath.Item和postID都应该匹配。

相关问题