2013-08-21 46 views
1

我真的很苦惱,希望有人能幫助。核心數據保存後自定義單元格標籤文本重疊

我正在使用核心數據,並使用fetchedResultsController填充TableView。對於我使用自定義的單元格類型。選擇一個細節後,細化視圖中,我改變了其中一個字段,並點擊保存,然後將我帶回到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; 
    } 

} 

回答

2

問題是您濫用樣板configureCell方法。

如果您看Apple的模板代碼,您會注意到它用於配置完全創建的單元格,即填充數據。

使用故事板時,可以大大省略單元格創建。通過故事板,通常不需要在if (cell==nil) {...}中創建東西。當然,如果你願意的話,你也可以在代碼中完成它,如果不是在if塊中,也可以單獨使用。我會建議稱這種方法createCell雖然,而不是configureCell

configureCell:然後,你可以把你的數據 - 你已經做的外部if區塊在cellForRowAtIndexPath:這實際上是進入configureCell的東西。

您現在正在這樣做的方式是在數據更改時在NSFetchedResultsControllerDelegate回調中創建新標籤。在NSFetchedResultsChangeUpdate的情況下(事實上確實發生了更改屬性時發生了什麼),但您要撥打configureCell,但configureCell會創建新視圖並將它們添加到單元格中。

因此,只需將您的單元格創建代碼從configureCell中移出,並將代碼填入數據單元格到configureCell,您應該沒問題。