如何在关系中插入新数据时更新tableView

时间:2012-12-11 21:14:31

标签: core-data tableview nsfetchedresultscontroller relation

我使用2个实体通过关系“事件”一对多连接的人和事件。在我的第一个表格视图中,我有第二个人的名字我有他们的事件类型。我可以向特定的人插入新事件,但第二个表视图也不会更新的问题。只有当我使用导航器回到人们身上并在它再次发生事件后我才能看到变化。

用于插入新事件我使用此方法:

- (void) addEventControllerDidSave:(NSString *)typeData{

    NSManagedObjectContext* context = [self managedObjectContext];
    Event *newEvent = (Event *)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context];
    [newEvent setType:typeData];
    [currentPerson addEventsObject:newEvent];

    NSError *error;
    if (![[self managedObjectContext] save:&error])
    {
        NSLog(@"Problem saving: %@", [error localizedDescription]);
    }

    [self dismissViewControllerAnimated:YES completion:nil];
}

我如何定义单元格:

//create cell use relation
    NSArray *eventsArray = [[[[self currentPerson] events] objectEnumerator]allObjects];
    Event *newEvent = [eventsArray objectAtIndex:indexPath.row];
    [[cell textLabel]setText: [newEvent type]];

更新表方法:

- (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:
        {
            NSArray *eventsArray = [[[[self currentPerson] events] objectEnumerator]allObjects];
            Event *newEvent = [eventsArray objectAtIndex:indexPath.row];
            UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
            [[cell textLabel]setText: [newEvent type]];
            break;
        }
        case NSFetchedResultsChangeMove:
        {
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        }
        default:
            break;
    }//switch
}

- (void) controller: (NSFetchedResultsController *) controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    switch (type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                          withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                          withRowAnimation:UITableViewRowAnimationFade];
            break;
        default:
            break;
    }
}

我真的不知道如何更新tableView是正确的,我更新了我的第一个tableView,但第二个有我早期描述的问题(也许是因为我使用关系?) 你也可以看到我的完整项目,直到现在git(也许它有帮助):

https://github.com/dennis87/eventCost

1 个答案:

答案 0 :(得分:1)

EventsTableController具有fetchResultsController属性和相应的_fetchResultsController实例变量。但此FRC始终为nil,因为它永远不会在EventsTableController中分配+初始化。

永远不会调用更新方法controllerWillChangeContentdidChangeObjectcontrollerDidChangeContent,因为您没有代理人的FRC。

作为解决方法,您可以添加

[self.tableView reloadData];
addEventControllerDidSave

,然后会立即看到新条目。

但真正的解决方案是初始化并使用FRC,正如您在NamesTableController中所做的那样。然后会自动显示新事件。


创建一个获取当前人的所有事件的获取结果控制器将如下所示(这是NamesTableController中的代码,经修改后可用于EventsTableController):

-(NSFetchedResultsController *) fetchResultsController{
    if (_fetchResultsController != nil) {
        return _fetchResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event"
                                              inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"person = %@", self.currentPerson];
    [fetchRequest setPredicate:predicate];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc]initWithKey:@"type" ascending:YES];
    NSArray *sortArray = [[NSArray alloc]initWithObjects:sort, nil];
    [fetchRequest setSortDescriptors:sortArray];

    _fetchResultsController = [[NSFetchedResultsController alloc]
                               initWithFetchRequest:fetchRequest
                               managedObjectContext:[self managedObjectContext]
                               sectionNameKeyPath:nil
                               cacheName:nil];

    _fetchResultsController.delegate = self;
    return _fetchResultsController;
}