UITableView accessoryType disappears in last half of UITableView
I have an iPad app (XCode 4.6, ARC, Storyboards, iOS 6.2.3). I have a UIPopover with a UITableView that has 21 rows in it. I can set the accessoryType in all of the rows randomly, but only in the first 12 rows does the accessoryType setting (checkmark) persist so it can be examined in another method and processed. I don't see any difference between the first 12 rows and the last 9 rows. The UITableView is scrollable, so to get to the rows after the 11th row, you have to scroll to the bottom
Here is the code to set the accessoryType :
#pragma mark didSelectRowAtIndexPath
- (void) tableView:(UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
// get the cell that was selected
UITableViewCell *theCell = [tableView cellForRowAtIndexPath:indexPath];
if(theCell.accessoryType != UITableViewCellAccessoryCheckmark)
theCell.accessoryType = UITableViewCellAccessoryCheckmark;
else
theCell.accessoryType = UITableViewCellAccessoryNone;
}
Here is the code where I check the accessoryType and process it:
-(void) moveServices { // (moves checked tableViewRows to services tableview)
NSMutableString *result = [NSMutableString string];
for (int i = 0; i < [servicesArray count]; i++) {
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];
[tvServices scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
UITableViewCell *cell = [tvServices cellForRowAtIndexPath:path];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
[result appendFormat:@"%@, ",cell.textLabel.text];
NSLog(@"nni: %dncell.accessoryType: %dncell.textLabel: %@",i,cell.accessoryType, cell.textLabel);
}
}
if (result.length > 2) { // move to text box in main menu
storeServices =[result substringToIndex:[result length] - 2];
}
}
It looks like you're mixing the notion of "data source" and the contents of the cells in the table. Don't do that -- keep your data source (whether or not a particular row in the table should display a checkmark based on your program logic) separate from the settings of particular cells (whether or not a particular cell displays a checkmark). Then in cellForRowAtIndexPath
, you build the cell to match your data source's current settings. The reason is that UITableView reuses cell instances based on which rows are visible on-screen (and it's just good MVC design).
In your case you should keep an NSMutableArray
property in your class that records the settings for the entire table, and use the value from that array in cellForRowAtIndexPath
to set up that particular cell. Then the other "business logic" methods in your controller use the array property to query your model state instead of the cell settings (which are part of the view and should be independent from the data model).