我想要实现的是 UITableView 快速重新加载。每个单元格都有“检查” UIButton wchich 告诉用户该单元格的项目已被选中。所有选定的单元格都应位于列表的末尾(底部单元格)。
我使用 NSFetchResultsController 作为 UITableView 的委托和数据源。NSFetchResultsController 设置为使用“Item”实体操作,其中为“checked”属性选择了 sectionKey(部分 od“Item”实体 which )
- (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 (项目实体)中的“已检查”属性并保存上下文。然后通知我的 NSFetchReslutsController 一项更改了它的状态,并使用函数执行 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 UITableView 的 sectionKey 应该在这种情况下重新加载
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationNone];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationNone];
break;
这是一个问题,因为当插入或延迟单元格时,UITableView 会执行持续时间约为 0.5 秒的动画。在这个时候 UITableView 停止接收下一个单元格的事件,因此当用户“检查”另一个单元格时,它不会收到有关该点击的通知。我想要实现的是让用户能够快速检查一些单元格,而无需等待动画结束。
可能的解决方案:
使用 reloadData 而不是 deleteRowsAtIndexPaths/insertRowsAtIndexPaths。这将不是动画,但重新加载所有 UITableView 的持续时间比重新加载一个单元格的时间长,所以在我的情况下,用户将等待 UITableView 重新加载 - 再次等待。有没有办法在不重新加载所有 UITableView 的情况下避免动画?
允许用户检查单元格,但仅在最后一次选择单元格后 0.5 秒后保存上下文。用户可以选择快速的多个单元格,当他结束选择时,所有更改都会传播到 UITableView - 我的老板希望将每个选定的单元格发送到第二部分而不分组,然后为每个选定的单元格重新加载 - 再次是个坏主意
也许一些自定义 tableView(用户创建,而不是苹果)?
首要目标:
使用户能够在每次“检查”后快速“检查”单元格刷新 UITableView
我对任何理想持开放态度:)