自定义单元格标签文本在核心数据保存后重叠

时间:2013-08-21 20:59:39

标签: iphone uitableview core-data custom-cell ios7

我真的很挣扎,希望有人可以提供帮助。

我正在使用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;
    }

}

1 个答案:

答案 0 :(得分:2)

问题是您滥用样板configureCell方法。

如果您查看Apple的模板代码,您会注意到它用于配置完全创建的单元格,即用数据填充它。

使用故事板时,可以大大省略单元格创建。使用storyboard,通常不需要在if (cell==nil) {...}中创建内容。当然,如果您愿意,您仍然可以在代码中执行此操作,如果不在if块中也可以在单独的方法中执行。我建议尽快调用此方法createCell,而不是configureCell

configureCell:中,您可以输入您的数据 - 您在cellForRowAtIndexPath:中的if块之外已经在做的事情。这实际上是configureCell中的内容。

您现在的方式是,当数据发生变化时,您将在NSFetchedResultsControllerDelegate回调中创建新标签。如果configureCell(确切地说是更改属性时发生的情况),您正在调用NSFetchedResultsChangeUpdate,但configureCell会创建新视图并将其添加到单元格中。

因此,只需将您的单元格创建代码移出configureCell,然后您的代码将数据填充到configureCell,您应该没问题。