问题
I'm trying to setup my table so that the user can select one item per section.
For example:
- Section 0
- Row 0 √
- Row 1
- Section 1
- Row 0
- Row 1 √
- Row 2
So in the above example if the user selects section 0, row 1
then row 0
in the same section should be unchecked and the selected row gets a checkmark.
Same goes for section 1 where any selected row should get a checkmark and then I want to remove the checkmark from the previously selected row in the same section.
- Section 0
- Row 0
- Row 1 √
- Section 1
- Row 0
- Row 1
- Row 2 √
Please keep in mind that I won't have a predefined number of sections or rows, so the code should work for this scenario. Here's what I currently have, hopefully that might get me started on the right path.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
MyObject *myObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if ([myObject.optionSelected boolValue] == NO) {
[myObject setOptionSelected:[NSNumber numberWithBool:YES]];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
} else {
[myObject setOptionSelected:[NSNumber numberWithBool:NO]];
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
if ([tableView numberOfRowsInSection:indexPath.section] > 1) {
NSMutableArray *cells = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < [tableView numberOfRowsInSection:indexPath.section]; ++i) {
[cells addObject:[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:indexPath.section]]];
}
for (UITableViewCell *deselectCell in cells) {
if ([self.tableView indexPathForCell:deselectCell] != indexPath && deselectCell != cell) {
MyObject *tempObject = [self.fetchedResultsController objectAtIndexPath:[self.tableView indexPathForCell:deselectCell]];
[tempObject setOptionSelected:[NSNumber numberWithBool:NO]];
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
}
}
}
As you can see I am also setting the object's selected state, I'd like this to remain intact :)
Thanks for any feedback and help in advance!
回答1:
Your tableview should declare a mutable array to hold the currently selected paths:
NSMutableArray *selectedCellPaths = [[NSMutableArray alloc] init];
Then your tableView:didSelectRowAtIndexPath:
should look like this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
MyObject *myObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if ([myObject.optionSelected boolValue] == NO) {
[myObject setOptionSelected:[NSNumber numberWithBool:YES]];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
[selectedCellPaths addObject:indexPath];
} else {
[myObject setOptionSelected:[NSNumber numberWithBool:NO]];
[cell setAccessoryType:UITableViewCellAccessoryNone];
if ([selectedCellPaths containsObject:indexPath]) {
[selectedCellPaths removeObject:indexPath];
}
}
// Now we're going to remove all but the cell path that is actually selected.
NSMutableArray *cellsToRemove = [[NSMutableArray alloc] init];
for (NSIndexPath *selectedCellIndexPath in selectedCellPaths) {
if ([selectedCellIndexPath compare:indexPath] != NSOrderedSame && selectedCellIndexPath.section == indexPath.section) {
// deselect cell at selectedCellPath
[cellsToRemove addObject:selectedCellIndexPath];
}
}
[selectedCellPaths removeObjectsInArray:cellsToRemove];
}
Note I have just put in a comment where you would want to deselect the actual cell at the cell path that is not selected. You need to fill that code in yourself.
I haven't tested this code, just modified what you had in TextMate but it should work barring minor changes.
来源:https://stackoverflow.com/questions/13037237/uitableviewcell-check-uncheck-within-one-section-only