DidSelectRowAtIndexPath select multiple rows at a time

I have a UITableView filled with 27 rows. I am trying to change the accessoryType selected cell. I do this in the delegate method didSelectRowAtIndexPath:

The problem I am facing is that when I select a row and change the accessoryType cell, the eleventh row of that row also changes.

I tried to print the value of [indexPath row] , but showed only the selected row and not another.

I am really puzzled by such things; please help me.

ADDED THE CODE cellForRowAtIndexPath Method

 UITableViewCell *cell; if ([indexPath row] == 0) { cell = [tableView dequeueReusableCellWithIdentifier:@"acell"]; } else { cell = [tableView dequeueReusableCellWithIdentifier:@"bcell"]; } cell.selectionStyle = UITableViewCellSelectionStyleNone; if (cell == nil && [indexPath row] != 0) { cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier:@"bcell"] autorelease]; } else if(cell == nil && [indexPath row] == 0){ cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier:@"acell"] autorelease]; } if ([cell.contentView subviews]){ for (UIView *subview in [cell.contentView subviews]) { [subview removeFromSuperview]; } } if ([indexPath row] == 0) { cell.textLabel.text = @"Select All"; cell.textLabel.font = [UIFont boldSystemFontOfSize:13.0f]; } else { cell.textLabel.text = @"Some Text Here" cell.detailTextLabel.text = @"Another piece of text here" } return cell; 

I do %10 because the behavior repeats after the 11th line, so it tries to create a new object for every 11th line.

My didSelectRowAtIndexPath methos code

 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if (cell.accessoryType == UITableViewCellAccessoryCheckmark) { if ([indexPath row] != 0) { NSIndexPath *tempIndex = [NSIndexPath indexPathForRow:0 inSection:0]; UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIndex]; tempCell.accessoryType = UITableViewCellAccessoryNone; } cell.accessoryType = UITableViewCellAccessoryNone; } else{ cell.accessoryType = UITableViewCellAccessoryCheckmark; } if ([indexPath row] == 0) { for (int i = 0; i < [dataSource count]; i++) { NSIndexPath *tempIndex = [NSIndexPath indexPathForRow:i+1 inSection:0]; UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIndex]; if (cell.accessoryType == UITableViewCellAccessoryCheckmark) { tempCell.accessoryType = UITableViewCellAccessoryCheckmark; } else{ tempCell.accessoryType = UITableViewCellAccessoryNone; } } } 

Please help me with several options or any other way to solve the multiple choice problem.

Thanks in advance!

+6
source share
2 answers

Here is one way to do this:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } [cell.textLabel setText:[NSString stringWithFormat:@"Row %d", indexPath.row]]; NSIndexPath* selection = [tableView indexPathForSelectedRow]; if (selection && selection.row == indexPath.row) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; } // Configure the cell. return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; } - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; } 

Remember that each cell in the table view is actually the same object that is reused. If you do not set the type of accessory every time cellForRowAtIndexPath is called, when new cells scroll to the screen, they all have the same accessory.

Multiple choice

For multiple choices, this is a little trickier.

Your first option: Undocumented API

Please note that this only works in table editing mode. Set the editing style of each cell for the undocumented UITableViewCellEditingStyleMultiSelect. Once you do this, you can get a view of the table view through the undocumented UITableView element: indexPathsForSelectedRows. This should return an array of selected cells.

You can expose this bit of functionality by placing it in the header:

 enum { UITableViewCellEditingStyleMultiSelect = 3, }; @interface UITableView (undocumented) - (NSArray *)indexPathsForSelectedRows; @end 

Then set the editing style for each cell as follows:

 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewCellEditingStyleMultiSelect; } 

When the table is in edit mode, you will see controls with multiple selections in your cells.

To view other undocumented APIs, you can use the nm command line utility as follows:

 nm /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit 

The second option: manage your choice yourself

Your subclass of UITableView has an array that indicates which cells are selected. Then in cellForRowAtIndexPath, adjust the appearance of the cell using this array. Your didSelectRowAtIndexPath method should look something like this:

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if ([tableView indexPathIsSelected:indexPath]) { [tableView removeIndexPathFromSelection:indexPath]; } else { [tableView addIndexPathToSelection:indexPath]; } // Update the cell appearance somewhere here [tableView deselectRowAtIndexPath:indexPath animated:NO]; } 

This assumes you are creating the indexPathIsSelected, removeIndexPathFromSelection, and addIndexPathToSelection methods in a subclass of UITableView. These methods should do exactly what their names mean: Add, delete, and check the index paths in the array. If you enable this option, you will not need the didDeselectRowAtIndexPath implementation.

+15
source

Remember that each cell in the table view is actually the same object that is reused. If you don't set the type of accessory every time cellForRowAtIndexPath is called, when new cells scroll to the screen, they all have the same accessory. "- daxnitro

That's where I got caught. I had my setup in such a way that in my cellForRowAtIndexPath function, I would only change the accessory for those specified in my array of checked cells, when what I had to do was update the accessory for all the cells in the table.

In other words:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //normal set up //retrieve key NSUserDefaults *settings = [NSUserDefaults standardUserDefaults]; id obj = [settings objectForKey:@yourKey]; //if the array is not populated, keep standard format for all cells if (obj == nil){ selectedStyles = [[NSMutableArray alloc] initWithObjects:nil]; [cell setAccessoryType:UITableViewCellAccessoryNone]; //no check mark [cell textLabel].textColor = [[UIColor alloc] initWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:1.0]; //keep black color } //else retrieve information from the array and update the cell accessory else{ //if the cell is in your array, add a checkbox [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; //add check box [cell textLabel].textColor = [[UIColor alloc] initWithRed:50.0/255 green:79.0/255 blue:133.0/255 alpha:1.0]; //change color of text label //if the cell is not in your array, then keep standard format [cell setAccessoryType:UITableViewCellAccessoryNone]; //no check mark [cell textLabel].textColor = [[UIColor alloc] initWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:1.0]; //keep black color 

Hope this helps!

0
source

Source: https://habr.com/ru/post/888529/


All Articles