UITableView having problems replacing an accessory when choosing

I use UITableView to select one (many) elements. Like the UI when choosing a ringtone, I want the selected item to be checked, and others not. I would like the cell to be selected when touched and then animated back to its normal color (again, like the user interface for selecting ringtones).

The subclass of UIViewController is my table delegate and data source (not a UITableViewController, because I also have a toolbar).

I install a cell type accessory in cellForRowAtIndexPath :, and update my model when cells are selected in the didSelectRowAtIndexPath: file. The only way I can set the selected cell to check (and clear the previous one) is to call [tableView reloadData] in the didSelectRowAtIndexPath: file. However, when I do this, the cell selection animation is strange (a white square appears where the cell label should be). Unless I call reloadData, of course, the accessoriesType type will not change, so no checkmarks will appear.

I suppose I could turn off the animation, but it seems lame. I also played with getting and modifying the cells in the didSelectRowAtIndexPath: file, but this is a big pain.

Any ideas? Short code follows ...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell* aCell = [tableView dequeueReusableCellWithIdentifier:kImageCell]; if( aCell == nil ) { aCell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:kImageCell]; } aCell.text = [imageNames objectAtIndex:[indexPath row]]; if( [indexPath row] == selectedImage ) { aCell.accessoryType = UITableViewCellAccessoryCheckmark; } else { aCell.accessoryType = UITableViewCellAccessoryNone; } return aCell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; selectedImage = [indexPath row] [tableView reloadData]; } 
0
source share
7 answers

I had the same problem and it was never solved.

In the end, it was a moot point for me, because I had to listen to changes in the model (the choice could change the outwith the user control if the connection was disconnected), so I just changed the model and let the notification reload the data, but it looked not too pretty (it was like a non-resuscitation selection, but start the end iteration loop!)

I suspect that the only way to do this is, you think, to keep the cache of links to the cells themselves. This should not be too dirty if you are writing a subclass of UITableViewCell to encapsulate logic by overriding -prepareForReuse.

However, it’s not very beautiful, and if the ringtones guys from Apple should have done it this way, they should have worked harder on the UITableView team to fix it!

EDIT:

Well, what do you know ?! In the end, it is really easy. - [UITableView cellForRowAtIndexPath] will provide you the actual cells (or nil if they are behind the scenes), and you can just change the type of accessories.

+4
source

I solved this, as suggested by the tail in editing it. In my code example, make sure that only one line is checked, but I'm sure you can configure it if that is not what you need.

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { int newRow = [indexPath row]; int oldRow = [lastIndexPath row]; if (newRow != oldRow) { UITableViewCell *newCell = [tableView cellForRowAtIndexPath: indexPath]; newCell.accessoryType = UITableViewCellAccessoryCheckmark; UITableViewCell *oldCell = [tableView cellForRowAtIndexPath: lastIndexPath]; oldCell.accessoryType = UITableViewCellAccessoryNone; lastIndexPath = indexPath; } [tableView deselectRowAtIndexPath:indexPath animated:YES]; } 
+8
source

I have a cleaner way to do this.

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if (cell.accessoryType == UITableViewCellAccessoryNone) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; } } 
+2
source

I use this simple and nice working mechanism with reloadRowsAtIndexPaths.

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSArray *rowsArray = [NSArray arrayWithObjects:indexPath, selectedIndexPath, nil]; self.selectedIndexPath = indexPath; [tableView reloadRowsAtIndexPaths:rowsArray withRowAnimation:UITableViewRowAnimationNone]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ .... skipped usual code ..... if ([selectedIndexPath compare:indexPath] == NSOrderedSame) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; } return cell; } 
+2
source

This will work as desired ...

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { int newRow = [indexPath row]; int oldRow = [lastIndexPath row]; if (newRow == oldRow){ UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if (cell.accessoryType == UITableViewCellAccessoryNone) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; } lastIndexPath = indexPath; } if (newRow != oldRow) { UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath]; newCell.accessoryType = UITableViewCellAccessoryCheckmark; UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath]; oldCell.accessoryType = UITableViewCellAccessoryNone; lastIndexPath = indexPath; } [tableView deselectRowAtIndexPath:indexPath animated:YES]; } 
+1
source
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:index]; oldCell.accessoryType = UITableViewCellAccessoryNone; UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryCheckmark; index = indexPath; } 
0
source

The answer is found in another section here in SOF, it works like a charm: iPhone: CellAccessory UITableView checkmark

0
source

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


All Articles