Disable prepareForReuse for selected cell

不羁岁月 提交于 2020-01-17 04:14:09

问题


I have a custom UITableViewCell. When a cell gets selected, a UILabel gets added to it. I had to use prepareForReuse for it not to get messy, like so:

- (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;
}

The problem is when I scroll down enough that the label is out of view, and then I scroll back up, the label isn't there anymore. The reason is obviously because when the cells get reused, I removed all the labels.

So is there a way to disable prepareForReuse (or just the code in the method) for the selected row, and how?


回答1:


Think of table cells as dumb containers that get reused to hold different things (labels, images, buttons, etc.).

You fill the cells in cellForRowAtIndexPath.

You empty them in prepareForReuse so they can be filled again and reused.

Don't confuse these two actions.

When you fill the cell, you should be filling it from data that you have stored somewhere else - i.e. not from other cells. If you are relying on indexPathsOfSelectedCells to help you when filling your cell, you are going to have problems. Don't do this.

Typically you would have an array of objects, where each object corresponds to a cell. You have as many cells in your table as objects in the array. You might initialize the objects in your array in viewDidLoad, or pass them in from a previous view controller.

This process doesn't have to be complicated. Most cells display only a few bits of data, so your object (often called a model) doesn't have to have many properties to hold this data.

When the user selects a cell, set a "selected" property in its corresponding object to indicate this. This value stays around in the object even when the cell is scrolled off the screen and reused. That's good.

Now when the user scrolls back to the cell, you fill the cell with data from the corresponding object. Since that object has its "selected" property set, you "fill" the cell by adding the label that you want there in this case. Or if it isn't set, you don't add the label.

In prepareForReuse, always remove the label to put the cell in its empty state, ready to be refilled.




回答2:


Cells that are scrolled away will be reused, and there's no way around it. Even if you avoid the removeFromSuperview logic, that cell will reappear at a different index path, probably not where you want it.

The way to conditionally configure cells is in cellForRowAtIndexPath. There, you can ask if the indexPath is among the table view's indexPathsOfSelectedCells. If it is, then configure it with the extra labels, or not, if not.

One way to reduce the messiness is to have those labels remain in the cell unconditionally, just setting their alphas to 0 or 1, depending on the selection state.

For example, in

- (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;

The larger point is, this is the suggested place to reliably configure a cell based on the model and its current position in the table



来源:https://stackoverflow.com/questions/28337041/disable-prepareforreuse-for-selected-cell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!