0

1対多の関係「イベント」で接続された2つのエンティティPersonとEventを使用します。最初のテーブル ビューでは、2 番目のテーブル ビューには Person の名前があり、そのイベント タイプがあります。特定の人に新しいイベントを挿入できますが、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 を更新しますが、2 番目の tableView には以前に説明した問題があります (おそらくリレーションを使用しているためでしょうか?) git で今までの完全なプロジェクトを見ることもできます (たぶん助けになる):

https://github.com/dennis87/eventCost

4

1 に答える 1

1

EventsTableControllerは、fetchResultsControllerプロパティと対応する_fetchResultsControllerインスタンス変数があります。しかし、この FRC は常にnil割り当てられていないため、EventsTableController.

デリゲートを持つ FRC がないため、更新メソッドcontrollerWillChangeContentdidChangeObject、が呼び出されることはありません。controllerDidChangeContent

回避策として、追加できます

[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;
}
于 2012-12-11T22:48:16.657 に答える