Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple checkMark when row selected in UITableView IOS

I have a UITableView that displays checkmarks when a row is selected. The problem is that When i select a row in didSelectRowAtIndexPath and add a checkmark on the selected row it adds an additional checkmark. Here's my code

Any help would be very much appreciated.

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    // Configure the cell...

    cell.textLabel.text=[[Model.category objectAtIndex:indexPath.row] categoryName];

    cell.imageView.image=[[Model.category objectAtIndex:indexPath.row]categoryImage];

    //cell.detailTextLabel.text =@"Breve Descripción de la categoria";

    return cell;

}

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

    if ([self.tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark) {

 [self.tableView cellForRowAtIndexPath:indexPath].accessoryType =UITableViewCellAccessoryNone;

 [self.cellSelected removeObject:indexPath];

    }else {

     [tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;

        [self.cellSelected addObject:indexPath];

    }

   [self checkMark];

   [tableView reloadData];   
}

- (void)checkMark{

    for (NSIndexPath * indexPath in self.cellSelected) {

       [self.tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;

    }


}
like image 241
Klinkert0728 Avatar asked May 18 '14 21:05

Klinkert0728


People also ask

How do I display a check mark when a row is selected?

To display a check mark when a row is selected, you just need to add two lines of code after the “ [messageAlert show]”: The first line retrieves the selected table cell by using the indexPath. The second link updates the accessory view of the cell with a check mark. Compile and run the app. After you tap a row, it’ll show you a check mark.

How do I clear the selection in a uitableviewcontroller?

If you’re using a UITableViewController to display a table view, you get the behavior by setting the clearsSelectionOnViewWillAppear property to true. Otherwise, you can clear the selection in your view controller’s viewWillAppear (_:) method:

What happens when a row is selected in the app?

When a row is selected, the app creates an UIAlertView and shows an alert message. Try to run the app and this is what the app looks like when you tap a row: For now, we just display a generic message when a row is selected.

Can Table View have multiple selections?

In the first two parts, we created the Table View with dynamic cells of different types, and we added a collapsible sections feature. Today, we will go through another common-used Table View scenario: multiple selections.


Video Answer


2 Answers

[self.tableView cellForRowAtIndexPath:indexPath] call in the didSelectRowAtIndexPath will not return the exact cell. It can be same cell, new cell or reused cell. If it is a reused cell at its accessory view has a checkmark, you will end up having two cells with checkmark.

Its better to store in the array and use it accordingly. If you are planning to have multiple selections, Use the code example below.

- (void)viewDidLoad
{
    [super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.
    self.cellSelected = [NSMutableArray array];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   //Cell Initialisation here

    if ([self.cellSelected containsObject:indexPath])
    {
      cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else
    {
      cell.accessoryType = UITableViewCellAccessoryNone;

    }
    return cell;
}


 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    //if you want only one cell to be selected use a local NSIndexPath property instead of array. and use the code below
   //self.selectedIndexPath = indexPath;

    //the below code will allow multiple selection
    if ([self.cellSelected containsObject:indexPath])
    {
      [self.cellSelected removeObject:indexPath];
    }
    else
    {
       [self.cellSelected addObject:indexPath];
    }
    [tableView reloadData];
}
like image 115
nprd Avatar answered Oct 24 '22 17:10

nprd


Try this:

Declare in your .m file:

@interface MyViewController () {
        NSIndexPath *__selectedPath;
    }

In tableView:cellForRowAtIndexPath: check if given indexPath is the same as stored in ivar:

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

    if ([__selectedPath isEqual:indexPath]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    return cell;
}

In tableView:didSelectRowAtIndexPath store pointer to selected NSIndexPath or nil if cell has been deselect

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

    if (cell.accessoryType == UITableViewCellAccessoryNone) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        __selectedPath = indexPath;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
        __selectedPath = nil;
    }
}

I wrote it without checking in Xcode, so there could be some typos, but I show main idea. In my opinion you shouldn't call [self checkMark]; in your tableView:cellForRowAtIndexPath: method.

Moreover if you want to have only one selected cell at a time, you should't create NSMutableArray to store NSIndexPath. It seems yours cellSelected stores 2 NSIndexPaths at a time, that why you have this strange behaviour.

like image 34
Neru Avatar answered Oct 24 '22 15:10

Neru