可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a bit of a problem where my check marks that i apply to my rows in my UITableView get all mixed up when i scroll. Im pretty sure this has to do with how the iphone reuses the cells and when i scroll away from on that has a check mark it probably puts it back in when i gets a chance.
Could someone please give me some tips on how I might avoid this or possibly take a look at my methods and see if anything looks off?
I was thinking that maybe I could save each row selection that the user made and then check to see which rows were being displayed to make sure the correct ones got the checkmark but I could'nt see a way to do so.
Thanks so much.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; [cell setAccessoryView:nil]; } NSMutableArray *temp = [[NSMutableArray alloc]init]; for (int j = 0; j < [listOfRowersAtPractice count]; j++) { if ([[differentTeams objectAtIndex:indexPath.section] isEqualToString:[[rowersAndInfo objectForKey:[listOfRowersAtPractice objectAtIndex:j]]objectForKey:@"Team"]]) { [temp addObject:[listOfRowersAtPractice objectAtIndex:j]]; } } [cell.cellText setText:[temp objectAtIndex:indexPath.row]]; [temp removeAllObjects]; [temp release]; // Set up the cell... return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if (cell.accessoryType != UITableViewCellAccessoryCheckmark) { cell.accessoryType = UITableViewCellAccessoryCheckmark; }else { cell.accessoryType = UITableViewCellAccessoryNone; } }
回答1:
Yes save the state of the row which is selected and in cellforrowatindexpath after you get the cell reset it to default state and check the state of the row and change the state.
EDIT:
You can create a NSMutabaleArray with number of items equal to the number of items in your datasource which is the name temp in your code.
On select you can actually change the value at that index to some text like @"selected" in the above created array.
In your cellforrowatindexpath you can check this text if its selected or unselected and then change the property of the cell. Its like maintaining a bitmap state for selected and unselected states.
回答2:
Give this a go :
static NSString *CellIdentifier = [NSString stringWithFormat:@"Cell %d",indexPath.row];
I had the same problem on one of my app's.
As for the check marks, are you using a core data store at all?
If you are use the following....
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { NSManagedObject *item = [[self fetchedResultsController] objectAtIndexPath:indexPath]; if ([[item valueForKey:@"checks"] boolValue]) { cell.accessoryType = UITableViewCellAccessoryCheckmark; [cell.textLabel setTextColor:[UIColor redColor]]; [cell.detailTextLabel setTextColor:[UIColor redColor]]; } else { cell.accessoryType = UITableViewCellAccessoryNone; [cell.textLabel setTextColor:[UIColor blackColor]]; [cell.detailTextLabel setTextColor:[UIColor blackColor]]; } }
And......
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSManagedObject *selectedObject = [self.fetchedResultsController objectAtIndexPath:indexPath]; if ([[selectedObject valueForKey:@"checks"] boolValue]) { [selectedObject setValue:[NSNumber numberWithBool:NO] forKey:@"checks"]; } else { [selectedObject setValue:[NSNumber numberWithBool:YES] forKey:@"checks"]; } [managedObjectContext save:nil]; }
回答3:
You need to reset/clear all settings in the cell whenever you reuse the cell. So here, right after you get the cell,
you need to do something like
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; [cell setAccessoryView:nil]; } cell.accessoryType = UITableViewCellAccessoryNone // This and other such calls to clean up the cell
回答4:
You need refresh the accessoryType of cell, because the cell is reused then it inherited the accessoryType from a reused Cell, this is the solution:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"cellIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; //Refresh acessory for cell when tableview have many cells and reuse identifier if([self.tableView.indexPathsForSelectedRows containsObject:indexPath]){ cell.accessoryType = UITableViewCellAccessoryCheckmark; }else{ cell.accessoryType = UITableViewCellAccessoryNone; } cell.textLabel.text = @"Your text cell"; return cell; }
回答5:
it worked for me.. in cell for row at index path i had created a checkbox button.. after everytym tableview is scrolled cellForRowAtIndexPath Method gets called hence i had to add condition in cellForRowAtIndexPath to check whether a cell has a checked or unchecked button
static NSString *simpleTableIdentifier = @"SimpleTableCell"; SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; if (cell == nil) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"SimpleTableCell" owner:self options:nil]; cell = [nib objectAtIndex:0]; } cell.nameLabel.text = [tableData objectAtIndex:indexPath.row]; cell.thumbnailImageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]]; cell.prepTimeLabel.text = [prepTime objectAtIndex:indexPath.row]; checkbox = [[UIButton alloc]initWithFrame:CGRectMake(290, 5, 20, 20)]; [checkbox setBackgroundImage:[UIImage imageNamed:@"checkbox_empty.png"] forState:UIControlStateNormal]; [checkbox addTarget:self action:@selector(checkUncheck:) forControlEvents:UIControlEventTouchUpInside]; [cell addSubview:checkbox]; if(selectedRows.count !=0) { if([[selectedRows objectAtIndex:indexPath.row]integerValue]==1) { [checkbox setImage:[UIImage imageNamed: @"checkbox_full.png"] forState:UIControlStateNormal]; } else { [checkbox setImage:[UIImage imageNamed: @"checkbox_empty.png"] forState:UIControlStateNormal]; } } return cell; }
method to define selection of checkbox is as
- (IBAction)checkUncheck:(id)sender { UIButton *tappedButton = (UIButton*)sender; NSLog(@"%d",tappedButton.tag); if ([[sender superview] isKindOfClass:[UITableViewCell class]]) { UITableViewCell *containerCell = (UITableViewCell *)[sender superview]; NSIndexPath *cellIndexPath = [self.tableView indexPathForCell:containerCell]; int cellIndex = cellIndexPath.row; NSLog(@"cell index%d",cellIndex); [selectedRows insertObject:[NSNumber numberWithInt:1] atIndex:cellIndex]; } NSLog(@"%@",selectedRows); if([tappedButton.currentImage isEqual:[UIImage imageNamed:@"checkbox_empty.png"]]) { [sender setImage:[UIImage imageNamed: @"checkbox_full.png"] forState:UIControlStateNormal]; } else { [sender setImage:[UIImage imageNamed: @"checkbox_empty.png"] forState:UIControlStateNormal]; } }
do not forget to initialize selectedRows array.. happy coding...!!!