3

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

Ranjit
  • 4,576
  • 11
  • 62
  • 121
  • I would recommend at least using [tableView deselectRowAtIndexPath:indexPath animated:YES]; to deselect your cells. – shoughton123 Jan 31 '13 at 11:57
  • And [tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone]; to select your cells. Gives you the default IOS animations for selecting and deselecting cells. – shoughton123 Jan 31 '13 at 11:58
  • Hi @shoughton123, thanks for your reply, but what about when the table is loaded once again – Ranjit Jan 31 '13 at 12:22
  • Just save the selected index as a variable, when the table is reloaded simply use these methods to reselct the same index. – shoughton123 Jan 31 '13 at 16:19

4 Answers4

6

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;
}
Nate Potter
  • 3,222
  • 2
  • 22
  • 24
3

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

tounaobun
  • 14,570
  • 9
  • 53
  • 75
Anil Varghese
  • 42,757
  • 9
  • 93
  • 110
  • Ok thats fine, I will save the indexpath in an array, but the user can click it 100 times, then everytime the user clicks it will be added to the array. – Ranjit Jan 31 '13 at 12:14
  • Hi @Anil, thanks for your edit, how to check it in CellForRowAtIndexPath – Ranjit Feb 01 '13 at 06:11
  • Hi @Anil, their is one problem though, if I select 3 rows, what is happening is that it is only showing the third row as selected.If I select 4 rows, then it will show me only 4 th one as selected and the previous ones are deselected . – Ranjit Feb 01 '13 at 06:50
  • checkedIndexPath array contains only one indexPath?? check... I didn't try out this... Its from my logic b:) – Anil Varghese Feb 01 '13 at 07:01
  • try to print the all checkedIndexPath.row while enumerating inside the cellForRow to make sure that each one is different – Anil Varghese Feb 01 '13 at 07:17
  • Hi @Anil, check my code above. Also I checked the indexpath , by NSLog, " 2 indexes [0, 0]", " 2 indexes [0, 1]", " 2 indexes [0, 2]" – Ranjit Feb 01 '13 at 07:24
  • dude you are doing in a wrong way.. i will correct the code wait – Anil Varghese Feb 01 '13 at 07:39
  • Thanks, it is working now , but why it was not working previously, can you explain me – Ranjit Feb 01 '13 at 07:58
  • Iam busy with my work dude... I will explain you later..:) Vote for me and put a tick:):) – Anil Varghese Feb 01 '13 at 08:21
0

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

dark
  • 447
  • 1
  • 9
  • 21
0
  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"]];
        }
    
    }
    
Kiran eldho
  • 224
  • 1
  • 8