UITableViewCellAccessory Disappears When Scrolled Off Screen

前端 未结 5 514
独厮守ぢ
独厮守ぢ 2021-01-22 12:42

I have a UITableView filled with objects. In the didSelectRowAtIndexPath method i have a UITableViewCellAccessoryCheckmark appear when the row is selected and disappea

相关标签:
5条回答
  • 2021-01-22 13:19

    Try to store selected index in a array or dictionary for the selected cell in didSelectRow method, and in cellForRowAtIndexPath check if that index is available in array then checkmark the cell with setting accesoryType. Hope you understand

    0 讨论(0)
  • 2021-01-22 13:26

    This is what I find to work best:

    (just any code between "Add this" and "End Add this")

    Also, make sure you change "(Your Number ofRows)" to an object that either returns an int, or is an int itself. Such as myCustomArray.count, or 24.

    //In .h file add this
    NSMutableArray *indexArray;
    
    //in .m file 
    
    - (void)viewDidLoad {
        //Add this
        indexArray = [[NSMutableArray alloc] init];
        int i;
        for (i = 0; i <= (Your Number ofRows); i++) {
            [indexArray addObject:[NSNumber numberWithDouble:0]];
        }
    NSLog(@"indexArray = %@",indexArray);//You can check the console now to see if you have an array of "zeros" 
        //End Add this
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
    UITableViewCell *curCell = [beerTable cellForRowAtIndexPath:indexPath];
    
    
    if (curCell.accessoryType == UITableViewCellAccessoryCheckmark) {
        [curCell setAccessoryType:UITableViewCellAccessoryNone];
        compareCount = (compareCount - 1);
    
        //Add this
        [indexArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithDouble:0]]; 
        //End Add this
    
    
        if (tableView == [[self searchDisplayController] searchResultsTableView]) {
            NSString *objBeer = [searchResults objectAtIndex:indexPath.row];
            [compareBeers removeObject:[searchResults objectAtIndex:indexPath.row]];
            [compareCarbs removeObject:[carbAmount objectAtIndex:[beerNames indexOfObject:objBeer]]];
        }
        else {
            [compareBeers removeObject:[beerNames objectAtIndex:indexPath.row]];
            [compareCarbs removeObject:[carbAmount objectAtIndex:indexPath.row]];
        }
    
    }
    else {
        [curCell setAccessoryType:UITableViewCellAccessoryCheckmark];
        compareCount = (compareCount + 1);
    
        //Add this
        [indexArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithDouble:1]]; 
        //End Add this
    
        if (tableView == [[self searchDisplayController] searchResultsTableView]) {
            NSString *objBeer = [searchResults objectAtIndex:indexPath.row];
            [compareBeers addObject:[searchResults objectAtIndex:indexPath.row]];
            [compareCarbs addObject:[carbAmount objectAtIndex:[beerNames indexOfObject:objBeer]]];
        }
        else {
            [compareBeers addObject:[beerNames objectAtIndex:indexPath.row]];
            [compareCarbs addObject:[carbAmount objectAtIndex:indexPath.row]];
        }
    
    }
    
    if (compareCount > 0) {
        if (compareOn == YES){
        }
        else {
            compareButton.enabled = YES;
            UIImage *image = [UIImage imageNamed:@"redbutton.png"];
            [compareButton setImage:image];
        }
    }
    
    else {
        compareButton.enabled = NO;
        [compareButton setImage:nil];
        [compareButton setCustomView:nil];
    }
    
    }    
    
    
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    
    static NSString *CellIdentifier = @"CustomCell";
    
    CustomCell *cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
    
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    
        for (id currentObject in topLevelObjects){
            if ([currentObject isKindOfClass:[UITableViewCell class]]){
                cell =  (CustomCell *) currentObject;
                break;
            }
        }
    }
    
    // Setting separate tables correctly....
    
    //Add this
    if ([[indexArray objectAtIndex:indexPath.row] doubleValue] == 1) {
        cell.accesoryType = UITableViewCellAccesoryTypeCheckmark;
    } else {
        cell.accesoryType = UITableViewCellAccesoryTypeNone; 
    }
    //End Add this 
    
    return cell;
    }
    
    0 讨论(0)
  • 2021-01-22 13:27

    for anyone wanting a more generic approach and for multiple selected cells

    First create an (NSMutableArray *)selectedCells to keep track of the selected cells. Next implement the 2 delegate methods

    -(void)tableView:(UITableView *)tableView 
        didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
    //add the checkmark to cell when selected
    if ([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryNone){
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
    
    }
    
    //once selected add that selected cell to the selectedCells array 
    
    [self.selectedCells addObject:@(indexPath.row) ];
    
    }
    

    AND

    -(void)tableView:(UITableView *)tableView 
                     didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{ 
    
    //set the accessory type back to none 
    if([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark){
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
    }
    
    //remove the selected cells index from the selectedCells array
    [self.selectedCells removeObject:@(indexPath.row) ];
    
    }
    

    Now when ever you select a cell a checkmark is added and that indexPath.row is stored in to an NSMutableArray. When you deSelect that cell it removes the checkmark and removes it from the array. Meaning the array will only hold cells that are checked.

    We then use that array to give the cell the correct accessoryType in the cellForRowAtIndexPath method. This method is called every time the tableView requires a cell we tell it wether that sell requires to have a checkMark when created or not.

    -(UITableViewCell *)tableView:(UITableView *)tableView 
                    cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
     static NSString *CellIdentifier = @"Cell";
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if (cell == nil) {
      cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    
    //Create an NSNumber to hold the row of the cell to be created   
       NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
    
    //then ask the array if the selectedCells array has that object.
    //if it does then that cell needs a checkmark when created.
    
    if ([self.selectedCells containsObject:rowNsNum]){
       cell.accessoryType = UITableViewCellAccessoryCheckmark;
         }
    else { cell.accessoryType = UITableViewCellAccessoryNone;
         }
    
        [cell.textLabel setText:@"your contents"];
     }
    
     return cell;
     }
    
    0 讨论(0)
  • 2021-01-22 13:34

    UITableViewCell are recycled when you scroll. So when you scroll the tableView down and up again, the cell you see may be different from the previously visible cell.

    You need to reset the status of a cell everytime in cellForRowAtIndexPath. You code has this comment area // Setting separate tables correctly....

    This is where you do the setting. When this is called, check if the cell is supposed to show a checkmark, and set it accordingly

    0 讨论(0)
  • 2021-01-22 13:36

    Your cells get re-used as you scroll through the data (that's what the dequeueReusableCellWithIdentifier does). Your cell that got a checkmark in didSelectRowAtIndexPath gets recycled for a different row and no longer has any connection to the checked row.

    You need to set/unset the accessory view in cellForRowAtIndexPath so when the checked rows scroll back into view, they get checked appropriately.

    0 讨论(0)
提交回复
热议问题