简体   繁体   中英

Disabling a cell in didSelectRowAtIndexPath not working?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.userInteractionEnabled = NO;
}

I use the above code to disable a cell after a user clicks on it once. The problem I've run into is that when a cell is added to the table, that new cell is disabled, and the previously disabled one isn't anymore.

How can I fix this problem?

Cells get reused as the user scrolls the table. You need to keep track of which rows the user has disabled so in your cellForRowAtIndexPath you can set the userInteractionEnabled property (to YES or NO as needed) for every cell every time it is requested.

Update - more details.

You need to keep track of which index paths the user has selected. Add an instance variable of type NSMutableSet and add each indexPath to this in your didSelectRow... method.

Then in your cellForRow... method you need to check if the current indexPath is in the set or not. Based on the result you set the cell's userInteractionEnabled property:

cell.userInteractionEnabled = ![theSelectedPathsSet containsObject:indexPath];

where theSeletedPathsSet is your NSMutableSet instance variable.

This solution assumes the rows and sections in your table are fixed. If the user can do things that results in rows being added, removed, or moved, then you can't simply track the index paths. You need to use some other key to know which rows have been selected.

Are you using dequeueReusableCellWithIdentifier in your cellForRowAtIndexPath ?

You should have something like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *reuseIdentifier = @"myTableViewCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (!cell) {
      cell = [[ArticleTableViewCell alloc] init];
}
// customise cell here (like cell.title = @"Woopee";)
if (self.selectedCells containsObject:[NSString stringWithFormat:@"%d", indexPath.row]] {
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.userInteractionEnabled = NO;
}
return cell;
}

Expanding on the other answer, you can keep track of whether a specific cell has been previously selected (are therefore should be disabled) by doing something like this with the above:

Declare a property like @property (nonatomic, strong) NSMutableArray *selectedCells; then:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
    [self.selectedCells addObject:[NSString stringWithFormat:@"%d", indexPath.row]];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.userInteractionEnabled = NO;
}

My laptop is about to die, but if it crashed you should look at the code the initialises the cell (alloc and init) or keep what you had before there.

You need to keep a record of which cells have been disabled. You could store the indexPath of the selected cells in an array and then use that to determine which cells should be active and not active in your cell:forRowAtIndexPath: method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM