我真的很挣扎,希望有人可以提供帮助。
我正在使用Core Data并使用fetchedResultsController填充TableView。对于我正在使用Custom的单元格类型。选择一个细分到细节视图的单元格后,我改变其中一个字段并点击Save,将我带回到tableview。唯一的问题是旧的字段文本仍然存在,新文本与它重叠。
我的tableviewcontroller.m具有以下代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
[self configureCell:cell atIndexPath:indexPath];
}
else {
// Cells all appear blank if I don't include the following line
[self configureCell:cell atIndexPath:indexPath];
Games *game = [self.fetchedResultsController objectAtIndexPath:indexPath];
UILabel *nwOpp = (UILabel *)[cell.contentView viewWithTag:401];
NSLog(@"nwOpp:%@", nwOpp.text);
nwOpp.text = [NSString stringWithFormat:@"%@", game.opponents.name];
UILabel *nwDate = (UILabel *)[cell.contentView viewWithTag:501];
NSLog(@"Date:%@", nwDate.text);
nwDate.text = [NSString stringWithFormat:@"%@ - %@" , [dateFormatter stringFromDate: game.date] , game.location];
UIImageView *nwImg2 = (UIImageView *)[cell.contentView viewWithTag:201];
nwImg2.image = game.opponents.image;
}
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
Games *game = [self.fetchedResultsController objectAtIndexPath:indexPath];
CGRect imageFrame = CGRectMake(70, 2, 20, 20);
UIImageView *customImage = [[UIImageView alloc] initWithFrame:imageFrame];
[customImage setContentMode:UIViewContentModeScaleAspectFill];
customImage.clipsToBounds = YES;
customImage.image = game.teams.image;
customImage.tag = 101;
[cell.contentView addSubview:customImage];
CGRect imageFrame2 = CGRectMake(230, 2, 20, 20);
UIImageView *customImage2 = [[UIImageView alloc] initWithFrame:imageFrame2];
[customImage2 setContentMode:UIViewContentModeScaleAspectFill];
customImage2.clipsToBounds = YES;
customImage2.image = game.opponents.image;
customImage2.tag = 201;
[cell.contentView addSubview:customImage2];
CGRect teamFrame = CGRectMake(0, 18, 140, 24);
UILabel *teamLabel = [[UILabel alloc] initWithFrame:teamFrame];
teamLabel.font = [UIFont boldSystemFontOfSize:14];
teamLabel.text = [NSString stringWithFormat:@"%@", game.teams.name];
teamLabel.textAlignment = NSTextAlignmentCenter;
teamLabel.tag = 301;
[cell.contentView addSubview:teamLabel];
CGRect versusFrame = CGRectMake(140, 18, 20, 24);
UILabel *versusLabel = [[UILabel alloc] initWithFrame:versusFrame];
versusLabel.font = [UIFont boldSystemFontOfSize:16];
versusLabel.text = @"vs";
versusLabel.textAlignment= NSTextAlignmentCenter;
[cell.contentView addSubview:versusLabel];
CGRect oppFrame = CGRectMake(160, 18, 140, 24);
UILabel *oppLabel = [[UILabel alloc] initWithFrame:oppFrame];
oppLabel.font = [UIFont boldSystemFontOfSize:14];
oppLabel.text = [NSString stringWithFormat:@"%@", game.opponents.name];
oppLabel.textAlignment = NSTextAlignmentCenter;
oppLabel.tag = 401;
[cell.contentView addSubview:oppLabel];
CGRect dateFrame = CGRectMake(10, 40, 300, 12);
UILabel *dateLabel = [[UILabel alloc] initWithFrame:dateFrame];
dateLabel.font = [UIFont systemFontOfSize:10];
dateLabel.text = [NSString stringWithFormat:@"%@ - %@" , [dateFormatter stringFromDate: game.date] , game.location];
dateLabel.textAlignment = NSTextAlignmentCenter;
dateLabel.tag = 501;
[cell.contentView addSubview:dateLabel];
}
我正在使用委托方法来保存数据更改:
-(void)EditGameViewControllerDidSave {
NSError *error = nil;
NSManagedObjectContext *context = self.managedObjectContext;
if (![context save:&error]) {
NSLog(@"Error! %@", error);
}
[self.navigationController popViewControllerAnimated:YES];
[self.tableView reloadData];
}
FetchedResultsController更改:
-(void) controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
-(void) controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch (type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
答案 0 :(得分:2)
问题是您滥用样板configureCell
方法。
如果您查看Apple的模板代码,您会注意到它用于配置完全创建的单元格,即用数据填充它。
使用故事板时,可以大大省略单元格创建。使用storyboard,通常不需要在if (cell==nil) {...}
中创建内容。当然,如果您愿意,您仍然可以在代码中执行此操作,如果不在if块中也可以在单独的方法中执行。我建议尽快调用此方法createCell
,而不是configureCell
。
在configureCell:
中,您可以输入您的数据 - 您在cellForRowAtIndexPath:
中的if块之外已经在做的事情。这实际上是configureCell
中的内容。
您现在的方式是,当数据发生变化时,您将在NSFetchedResultsControllerDelegate
回调中创建新标签。如果configureCell
(确切地说是更改属性时发生的情况),您正在调用NSFetchedResultsChangeUpdate
,但configureCell
会创建新视图并将其添加到单元格中。
因此,只需将您的单元格创建代码移出configureCell
,然后您的代码将数据填充到configureCell
,您应该没问题。