为选定的单元格禁用 prepareForReuse

Disable prepareForReuse for selected cell

我有一个习惯UITableViewCell。当一个单元格被选中时,一个 UILabel 被添加到它。我不得不使用 prepareForReuse 以免变得混乱,像这样:

- (void)prepareForReuse {
    NSArray *viewsToRemove = [self.view subviews];
    for (UILablel *label in viewsToRemove) {
        [label removeFromSuperview];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CategorieCell *customCell = [tableView dequeueReusableCellWithIdentifier:@"cellID" forIndexPath:indexPath];
    return customCell;
}

问题是,当我向下滚动到标签不可见,然后向上滚动时,标签不再存在。原因显然是因为当细胞被重复使用时,我删除了所有标签。

那么有没有办法为选定的行禁用 prepareForReuse(或仅方法中的代码),如何实现?

滚动离开的单元格将被重复使用,没有办法绕过它。即使您避免使用 removeFromSuperview 逻辑,该单元格也会重新出现在不同的索引路径中,可能不是您想要的位置。

有条件地配置单元格的方法在cellForRowAtIndexPath中。在那里,您可以询问 indexPath 是否在 table 视图的 indexPathsOfSelectedCells 中。如果是,则为其配置额外的标签,如果不是,则不配置。

减少混乱的一种方法是让这些标签无条件地保留在单元格中,只需将它们的 alpha 设置为 0 或 1,具体取决于选择状态。

例如,在

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    // if you know the table has singular selection
    NSIndexPath *selectedIndexPath = [tableView indexPathForSelectedRow];
    BOOL rowIsSelected = [indexPath isEqual:selectedIndexPath];

    // OR, for multiple select...
    NSArray *selection = [tableView indexPathsForSelectedRows];
    BOOL rowIsSelected = [selection containsObject:indexPath];

    // now either conditionally create/destroy or show/hide the subviews
    // that appear on selection (I prefer show/hide for simpler cells)...

    [cell configAsSelected:rowIsSelected];  // have the custom cell do it

    // in that method, or here, if you're less OO-inclined...
    cell.subviewThatAppearsOnSelected.alpha = (rowIsSelected)? 1.0 : 0.0;

更重要的是,这是根据模型及其在 table

中的 当前 位置可靠地配置单元格的建议位置

将 table 单元格视为哑容器,可以重复使用以容纳不同的东西(标签、图像、按钮等)。

您填写 cellForRowAtIndexPath 中的单元格。

您在 prepareForReuse 中将它们清空,以便再次填充和重复使用。

不要混淆这两个动作。

当您填充单元格时,您应该使用存储在其他地方的数据填充它 - 即不是来自其他单元格。如果您在填充单元格时依赖 indexPathsOfSelectedCells 来帮助您,那么您将会遇到问题。不要这样做。

通常您会有一个对象数组,其中每个对象对应一个单元格。 table 中的单元格与数组中的对象一样多。您可以在 viewDidLoad 中初始化数组中的对象,或从以前的视图控制器传入它们。

这个过程并不复杂。大多数单元格仅显示少量数据,因此您的对象(通常称为模型)不必具有很多属性来保存此数据。

当用户选择一个单元格时,在其对应的对象中设置一个"selected" 属性来表示这一点。即使单元格滚出屏幕并重新使用,该值也会保留在对象中。不错。

现在,当用户滚动回单元格时,您会用相应对象的数据填充单元格。由于该对象设置了 "selected" 属性,在这种情况下,您可以通过添加所需的标签来 "fill" 单元格。或者,如果未设置,则不添加标签。

在 prepareForReuse 中,始终移除标签以使单元格处于空状态,准备重新填充。