6

1 つのセクションと 2 つの行を持つ単純なテーブル ビューがあります。NSFetchedResultsControllerテーブルを CoreData と同期させるためにを使用しています。テーブル ビュー セルの更新と移動をトリガーする CD の行の 1 つに変更を加えます。問題は、のcellForRowAtIndexPath:間に が呼び出されるとNSFetchedResultsChangeUpdate、間違ったセルが返されることです (セルがまだ移動されていないため、これは理にかなっています)。したがって、間違ったセルが新しく更新されたデータで更新されます。その後、NSFetchedResultsChangeMoveメッセージが処理されるため、セルは場所を交換します (どちらのセルの内容も、単なる移動呼び出しであるため更新されません)。その結果、両方のセルが新しく更新された CD エンティティからのデータを反映します。テーブルをリロードすると、問題が修正されます。私は iOS 6 を実行しています。つまり、インデックス 0 のセルがエンティティ A を表し、インデックス 1 がエンティティ B を表し、2 つのセルの順序が逆になるようにエンティティ A を A' に更新すると、結果は次のようになります。 0:A' 1:A 0:B, 1:A' と予想される場合。

- (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:
//the wrong cell is updated here
            [self configureCell:(SyncCell*)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
//this code produces errors too
            //[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            //[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}
4

4 に答える 4

7

解決策は次のとおりです。

[self configureCell:(SyncCell*)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:newIndexPath ? newIndexPath : indexPath];

更新中に提供された新しいインデックス パスを使用します。そして、移動の代わりに削除と挿入を使用します。他の誰かが何か意見を持っているかどうか知りたいです。

于 2013-01-16T09:32:05.557 に答える
3

configureCell を呼び出すときは、渡されたオブジェクトに基づいて indexPath を検索します。この時点では、indexPath と newIndexPath の両方が信頼できません。例えば:

case NSFetchedResultsChangeUpdate:
    myPath = [controller indexPathForObject:anObject];
    if (myPath) {
        [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:myPath];
    }

    break;
于 2015-08-12T19:55:56.240 に答える