Reputation: 5
heres my code in didSelectRowAtIndexPath
. any suggestion or help on how to fix this please.. the problem is when i clicked the cell many cell will have checkmark ....My plan is when i clicked one cell only that cell will have Checkmark
- (void)tableView:(UITableView *)thetableView
didSelectRowAtIndexPath:(NSIndexPath *)newindexPath {
[thetableView deselectRowAtIndexPath:[thetableView indexPathForSelectedRow]
animated:true];
UITableViewCell *cell = [thetableView cellForRowAtIndexPath:newindexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
and heres the code in cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
object:(nullable PFObject *)object {
static NSString *cellIdentifier = @"attendance";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UILabel *student_lastname = (UILabel *)[cell viewWithTag:1];
UILabel *student_firstname = (UILabel *)[cell viewWithTag:2];
UILabel *student_midname = (UILabel *)[cell viewWithTag:3];
student_lastname.text = object[@"Last_Name"];
student_firstname.text = object[@"First_Name"];
student_midname.text = object[@"Middle_Name"];
UILabel *studentNum = (UILabel *)[cell viewWithTag:5];
studentNum.text = [NSString stringWithFormat:@"%d", indexPath.row];
return cell;
}
Upvotes: 0
Views: 281
Reputation: 1168
Not a fan of either answer provided. Apple's UITableView implementation forces you into MVC (model-view-controller). Cell views, since they can be reused, should never store state, which is what you're doing relying on cell.selected. All answers above will fail if there are more cells than fit on screen, since they will be reused.
Given that you already have an object to store data such as "Last_Name", etc. you should also store @"Selected" as well.
Here's what your code should look like:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
object:(nullable PFObject *)object {
static NSString *cellIdentifier = @"attendance";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UILabel *student_lastname = (UILabel *)[cell viewWithTag:1];
UILabel *student_firstname = (UILabel *)[cell viewWithTag:2];
UILabel *student_midname = (UILabel *)[cell viewWithTag:3];
student_lastname.text = object[@"Last_Name"];
student_firstname.text = object[@"First_Name"];
student_midname.text = object[@"Middle_Name"];
NSNumber *selectedVal = object[@"Selected"];
if (selectedVal && [selectedVal boolValue]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
UILabel *studentNum = (UILabel *)[cell viewWithTag:5];
studentNum.text = [NSString stringWithFormat:@"%d", indexPath.row];
return cell;
}
Then, in didSelect, you change the state of the cell and force a reload (of that cell only, if appropriate).
- (void)tableView:(UITableView *)thetableView
didSelectRowAtIndexPath:(NSIndexPath *)newindexPath {
NSNumber *selectedVal = object[@"Selected"];
BOOL selected = selectedVal ? ![selectedVal boolValue] : YES;
object[@"Selected"] = @(selected);
[thetableView reloadRowsAtIndexPaths:@[newindexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
Upvotes: 0
Reputation: 3234
So, I am assuming that you only want to show a checkmark if the cell is selected. Recommend you to update your question please.
The problem happens because your cells are being re-used when you scroll and you need to first set the accessory type accordingly in your cellForRowAtIndexPath
method like this:
if ([cell isSelected])
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
This is to ensure that whenever a cell is reused, you make sure that it does not have any checkmark if its not selected, and show a checkmark if selected.
Next use the following two methods to set the checkmark and remove it when the cell is unselected/selected like this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
Also, you should not call [thetableView deselectRowAtIndexPath:[thetableView indexPathForSelectedRow] animated:true];
This method is automatically called in your case.
Hope this solves your problem.
Upvotes: 1