私が達成しようとしているのは、UITableView のリロードが速いことです。各セルには、このセルのアイテムが選択されていることをユーザーに伝える「チェック」UIButton があります。選択したすべてのセルは、リストの最後 (一番下のセル) にある必要があります。
UITableView のデリゲートおよびデータ ソースとして NSFetchResultsController を使用しています。NSFetchResultsController は、"checked" プロパティに sectionKey が選択された "Item" エンティティで動作するように設定されています ("Item" エンティティの一部)
- (id)initWithItemView:(ItemView*)iv{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:[CoreDataHandler context]];
[request setEntity:entity];
NSArray *predicates = [NSArray arrayWithObjects:[iv listDBUsingContext:[CoreDataHandler context]],nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"lista IN %@ AND deletedDB == NO", predicates];
[request setPredicate:predicate];
[request setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"checked" ascending:YES selector:@selector(compare:)];
NSSortDescriptor *sortDescriptor2
= [[NSSortDescriptor alloc] initWithKey:@"position" ascending:YES selector:@selector(compare:)];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, sortDescriptor2, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
[sortDescriptor2 release];
if (self=[[FastTableDelegate alloc]
initWithFetchRequest:request
managedObjectContext:[CoreDataHandler context]
sectionNameKeyPath:@"checked"
cacheName:nil])
{
self.delegate = self;
self.itemView = iv;
self.heightsCache = [NSMutableDictionary dictionary];
}
[request release];
[self performFetch:nil];
return self;
}
次に、ユーザーがセルの UIButton をタップすると、NSmanagedObject (Item エンティティ) の "checked" プロパティを変更し、コンテキストを保存します。次に、私の NSFetchReslutsController は、1 つのアイテムが状態を変更したことを通知され、関数を使用して UITableView のリロードを実行します
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.itemView.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeUpdate:
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationNone];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationNone];
break;
}
}
NSFetchedResultsController の sectionKey である「checked」プロパティを変更したため、このシナリオで UITableView をリロードする必要があります
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationNone];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationNone];
break;
そして、セルが挿入またはデレートされると、 UITableView が約0.5秒のアニメーションを実行するため、問題があります。この間、UITableView は次のセルのイベントの受信を停止するため、ユーザーが別のセルを「チェック」すると、そのタップについて通知されません。私が達成しようとしているのは、ユーザーがアニメーションの終了を待たずにいくつかのセルをすばやくチェックできるようにすることです。
可能な解決策:
deleteRowsAtIndexPaths/insertRowsAtIndexPaths の代わりに reloadData を使用します。アニメーションはありませんが、すべての UITableView をリロードすると、1 つのセルをリロードするよりも長く続くため、私の場合、ユーザーは UITableView がリロードされるのを待ちます - 再び待ちます。すべてのUITableViewをリロードせずにアニメーションを回避する方法はありますか?
ユーザーがセルをチェックできるようにしますが、最後のセル選択から 0.5 秒後にのみコンテキストを保存します。ユーザーは複数のセルをすばやく選択でき、選択を終了すると、すべての変更が UITableView に伝達されます - 私の上司は、選択した各セルをグループ化せずに 2 番目のセクションに送信したいので、選択したセルごとに 1 回リロードします - これも悪い考えです。
たぶん、いくつかのカスタムtableView(Appleではなくユーザーが作成したもの)ですか?
主な目標:
ユーザーがセルをすばやく「チェック」できるようにし、各「チェック」後に UITableView を更新します。
私はどんな理想にもオープンです:)