How to toggle UITableView Cell selected status

2019-07-04 21:48发布

问题:

I have a UITableView with a custom Cell, the cell contains a UIImageView and a UILabel. Now When I load my table first time, It loads with a same image on each cell and different labels, which it takes from the LabelArray.

Now the image I am talking about is a radioButton, So when the user clicks the cell, the image changes. If user clicks again it changes to default state.

For this to happen, I have used this function and also I have declared a bool variable in my customcell class called selectionStatus.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell * cell = (CustomCell* )[tableView cellForRowAtIndexPath:indexPath];

    if(indexPath.row == 0)
    {
        if(cell.selectionStatus == TRUE)
        {           
            //Do your stuff
           cell.selectionStatus = FALSE;
        }
        else
        {
            //Do your stuff
            cell.selectionStatus = TRUE;
        }
    }

    if(indexPath.row == 1)
    {
        if(cell.selectionStatus == TRUE)
        {           
            //Do your stuff
           cell.selectionStatus = FALSE;
        }
        else
        {
            //Do your stuff
            cell.selectionStatus = TRUE;
        }
    }
}

This works fine, (but I want to know whether it is a proper way, or can we check the cell.selected property) and I am able to get that effect. But now when I close the View and open it again the function

Edit based on below comments with @Anil

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

    if([self.checkedIndexpath count]  == 0)
    {
        [tableCell.selectionImage setImage:@"xyz.png"];
    }
    else
    {        
        for (int i =0; i <[self.checkedIndexPath count]; i++)
        {
            NSIndexPath *path = [self.checkedIndexPath objectAtIndex:i];
            if ([path isEqual:indexPath])
            {               
                [tableCell.selectionImage setImage:@"abc.png"]
            }
            else
            {
                 [tableCell.selectionImage setImage:@"xyz.png"]            
             }
    }
return tableCell;

Regards Ranjit

回答1:

you have to save the index path of the selected row in didSelectRowAtIndexPath and check the index path in cellForRowAtIndexPath: set the corresponding image

Do you want multiple selection? try this...

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell * cell = (CustomCell* )[tableView cellForRowAtIndexPath:indexPath];

if(indexPath.row == 0)
{
    if(cell.selectionStatus == YES)
    {     
      [self.checkedIndexPaths addObject:indexPath];
        //Do your stuff
       cell.selectionStatus = NO;
    }
    else
    {
        [self.checkedIndexPaths removeObject:indexPath];
        //Do your stuff
        cell.selectionStatus = YES;
    }
}
}  

Edit
In cellForIndexPath check like this

 // Set the default image for the cell. imageXYZ   
for (NSIndexPath *path in self.checkedIndexPath) 
{
    if ([path  isEqual:indexPath])
    {
        //set the changed image for the cell. imageABC
    }
    // no need of else part
}

Do the exact we will see



回答2:

Another option for toggling UItableViewCells...

In the willSelectRowAtIndexPath return nil for NSIndexPath if cell is already selected, also set your _selectedIndexPath instance variable.

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    if (cell.selected) {
        [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
        [self.tableView.delegate tableView:self.tableView didDeselectRowAtIndexPath:indexPath];
        indexPath = nil;
    }

    _selectedIndexPath = indexPath;

    return indexPath; 
}

In didSelectRowAtIndexPath and didDeselectRowAtIndexPath update your cell based on the property cell.selected ...

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    if (cell.selected) {
        // do stuff
    } else {
        // do stuff
    }
}

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    if (cell.selected) {
        // do stuff
    } else {
        // do stuff
    }; 
}

and finally in viewDidLoad set the clearsSelectionOnViewWillAppear property...

- (void)viewDidLoad {
    [super viewDidLoad];
    self.clearsSelectionOnViewWillAppear = NO;
}


回答3:

Take a boolean in your model class and update it on didSelectRow method and reload table. In cellForRowAtIndexPath check this like that.

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

 After making your cell check like that 

    ModelClass *yourModel=[self.yourArray objectAtIndex:indexPath.row];
   if(yourModel.selection)
     [cell.customImage setImage:[UIImage imageName:@"selected"]; 
  else
     [cell.customImage setImage:[UIImage imageName:@"un_selected"];

}

Check this link https://github.com/adnanAhmad786/Quiz-View--TableView



回答4:

  1. First of all for toggling purpose declare a bool value selectionStatus in tableview cell class like this:

    @property(nonatomic)BOOL selectionStatus;

  2. Declare a NSMutableArray to store the selected indexpaths (for multi-selection purpose)

    self.checkedIndexPaths = [[NSMutableArray alloc] init];

  3. In didSelectRowAtIndexPath

    a. if Bool value selectionStatus is No Insert indexPath to NSMutableArray checkedIndexPaths and set cell.selectionStatus = YES

    b. if Bool value selectionStatus is Yes Remove indexPath from NSMutableArray checkedIndexPaths and set cell.selectionStatus = NO

    c. Reload tableView each time

Find the code below :

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

    tableCell = [self.tableView cellForRowAtIndexPath:indexPath];


        if(cell.selectionStatus == YES)
        {
            [self.checkedIndexPaths removeObject: indexPath];
            cell.selectionStatus = NO;

        }
        else
        {

            [self.checkedIndexPaths addObject: indexPath];
            cell.selectionStatus = YES;


        }

    [self.tablee reloadData];
}
  1. In cellForRowAtIndexPath

    a. First set cell image to unchecked i.e xyz.png here

    [tableCell.selectionImage setImage:[UIImage imageNamed:@"xyz.png"]];

    b. Set image as checked for all index paths in NSMutable array self.checkedIndexPaths

    for (NSIndexPath *path in self.checkedIndexPaths)
    {
        if ([path  isEqual:indexPath])
        {
            [tableCell.selectionImage setImage:[UIImage imageNamed:@"abc.png"]];
        }
    
    }