禁用所选单元格的prepareForReuse

时间:2015-02-05 05:50:34

标签: ios objective-c uitableview custom-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(或只是方法中的代码),以及如何?

2 个答案:

答案 0 :(得分:1)

滚动的单元格将被重用,并且无法绕过它。即使你避免使用removeFromSuperview逻辑,该单元格也会重新出现在不同的索引路径上,可能不在你想要的位置。

有条件地配置单元格的方法是在cellForRowAtIndexPath中。在那里,您可以询问indexPath是否在表视图的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;

更重要的是,这是根据模型及其在表中的当前位置可靠地配置单元格的建议位置

答案 1 :(得分:0)

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

填充cellForRowAtIndexPath中的单元格。

你在prepareForReuse中清空它们,这样它们就可以再次填充并重复使用。

不要混淆这两个行为。

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

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

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

当用户选择单元格时,在其对应的对象中设置“selected”属性以指示此情况。即使单元格从屏幕滚动并重复使用,该值仍保留在对象中。那很好。

现在,当用户滚动回单元格时,您将使用相应对象中的数据填充单元格。由于该对象具有“selected”属性集,因此在这种情况下通过添加所需的标签来“填充”单元格。或者,如果未设置,则不添加标签。

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