如何暂时停止某些 UITableViewCell 的重复使用? (或唯一标识一个单元格,即使它被重复使用)

How to temporarily stop certain UITableViewCell's from being reused? (or uniquely identify a cell even if its been reused)

我目前有一个设置,在网络进程完成时,点击一个单元格会导致 activity 指示器出现在单元格上。完成后,单元格会自动更新其 UI.

问题是,在这种情况下,如果用户将单元格滚动到屏幕之外,它当前会被重新使用,而当您向后滚动时,该单元格要么处于预点击 UI,要么post-点击 UI(取决于进程是否在用户滚动离开时完成)。

从用户的角度来看,这使得正在进行的后台操作似乎只是 运行domly 停止,但它仍在发生,只是 UI 得到刷新。

所以我正在努力解决如何暂时阻止单元格的重用,或者有什么方法可以在单元格上(并且仅在该单元格上)保持一致的加载指示器,即使在重用后也是如此?

编辑: 用一些数据来保存 indexPath 的想法是朝着正确方向迈出的一步,但排序是可能的,但不是gua运行保持不变。

所以我猜问题变成了:我需要找到一些唯一的东西来识别给定的单元格,当我收到代表调用过程已完成时。我尝试使用标签的文本,因为它是 "unique"(99% 的时间......)但这只是 gua运行 工作,除非我也传递 "unique" 标识符(标签,这甚至不是 gua运行teed 是独一无二的)在我的支持下乘坐有趣的过山车 类 只是为了它可以在最后使用。


我尝试过的事情

1) 尝试: 通过在加载时将单元格放置在 NSMutableArray 属性 中来保留单元格,并使用一个委托方法在它完成后将其删除,即:

[self.loadingCells addObject:cell];

结果:无效果


2) 尝试: 添加一个 属性 到 UITableViewCell(我子类化)称为 isLoading.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    if (cell.isLoading) {
        [cell.activityView startAnimating];
    }
}

结果: 在正确的单元格上加载指示器,但在屏幕外也加载其他单元格。

工作得体,但我 运行 进入其他 运行dom 单元格的问题,现在神秘地看起来它们正在加载,因为原始单元格被重新用于制作它们。


3) 尝试: 与尝试#1 相同,除了使用(唯一)单元格的标签文本:

[self.loadingCells addObject:cell.label.text];

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    if ([self.loadingCells containsObject:cell.label.text]) {
        [cell.activityView startAnimating];
    }
}
// delegate method
- (void)finishedLoading:(MyCell *)cell {
    [cell.activityView stopAnimating];
    [self.loadingCells removeObject:cell.label.text];
}

结果: 仅在正确的单元格上加载指示器,但如果进程完成时单元格不在屏幕上,委托方法会尝试删除错误的标签文本,从而导致单元格看起来像是在永久加载.


4) 然后我继续在委托方法上传递一个 NSString 并尝试比较它们并删除正确的字符串......这也给出了不可靠的结果。 我认为这是因为传递给处理网络调用的 类 的单元格可能不会保持静态,因此如果我在调用提取标签时碰巧没有显示单元格文本将不正确。

所以我 可以 立即创建 NSString 并通过我在不同 类 中进行的精彩调用网络传递它,但这太荒谬了,我当时已经不喜欢这个解决方案...

你不应该将这种类型的数据存储在一个单元格上,我保证你绝对不想让这些单元格被重复使用。这是 UITableView 背后最强大的功能之一,也是它发展如此之快的原因。

处理此问题的最佳方法是使用数组或其他类型的数据存储来保存用于 "configure" 您的单元格的所有数据。本质上,有一个数组,您可以检查它是 cellForItemAtIndexPath 以查看单元格是否需要指示符。然后根据此数据相应地配置单元格。这样你实际上不需要在单元格中保持状态。

很难准确设计如何完成此操作,但这里有一个非常人为的示例,说明如何使用地图检查单元格是否已加载。如果该单元格不在地图中,他们可以使用默认值添加它并照常进行处理。

//: Playground - noun: a place where people can play

import UIKit

let index1 = NSIndexPath(forRow: 0, inSection: 0)
let index2 = NSIndexPath(forRow: 1, inSection: 0)
let index3 = NSIndexPath(forRow: 2, inSection: 0)
let index4 = NSIndexPath(forRow: 3, inSection: 0)

var cellIsLoadingMap = [NSIndexPath: Bool]()
cellIsLoadingMap[index1] = true
cellIsLoadingMap[index2] = true
cellIsLoadingMap[index3] = false
cellIsLoadingMap[index4] = false

let index5 = NSIndexPath(forRow: 4, inSection: 0)

if let isLoading = cellIsLoadingMap[index5] {
    print(isLoading)
} else {
    cellIsLoadingMap[index5] = false
}