我有一个超过1000个单元格的表格视图(我在屏幕上显示大约10个)。在用户执行“过滤”操作之后,我想删除大约80%的用户,然后在第二次过滤后另外80%。当使用100个单元时,它大致是瞬间的,但是1000只需要0.5秒才能完成方法[tableView endUpdates],这完全破坏了用户体验。
我创建了像这样的索引路径数组:
for (int i=1; i<[appDelegate.myArray count]; i++) { //more than 1000 objects in myArray
if (![[appDelegate.myArray objectAtIndex:i] myTest]) { //myTest returns a BOOL
[appDelegate.rowsToDelete addObject:[NSIndexPath xxxxx]]; //the index path of the object that just failed the test and must be removed];
}
}
[self.myTableViewController.tableView deleteRowsAtIndexPaths:appDelegate.rowsToDelete withRowAnimation:UITableViewRowAnimationRight];
我尝试了2个解决方案,其中一个是线程化,这样我的用户就可以看到UI的其他部分正在移动,而tableView正在更新。但如果他启动另一级别的过滤,这通常会导致漫长的等待,如果不是崩溃。
我还尝试删除前几个单元格(屏幕上的那些单元格),然后从数据源中删除其他未通过测试的对象,而不从tableView中移除相应的单元格,因为它们看不见。这给出了良好,快速的结果,但是我遇到了行数问题,例如:
'无效更新:第0节中的行数无效。更新后现有部分中包含的行数(94)必须等于更新前该部分中包含的行数(927)加上或减去从该部分插入或删除的行数(插入0,删除215)。'
有人有这样的性能问题吗?解决方法? 干杯, CD
答案 0 :(得分:0)
尝试缓存属性并对循环使用快速枚举:
//int i = 0;
NSMutableArray *rowsToDelete = appDelegate.rowsToDelete;
for(id current in appDelegate.myArray) {
if([current myTest]) [rowsToDelete addObject:[NSIndexPath ...]];
//++i;
}
[self.myTableViewController.tableView deleteRowsAtIndexPaths:rowsToDelete withRowAnimation:UITableViewRowAnimationRight];
如果使用项目的索引创建NSIndexPath,请取消注释第一行和第五行。另外,我注意到你的代码中你从i = 1开始。由于NSArrays从0开始,因此永远不会删除第一个单元格。如果您确实想要这个,请将i = 0更改为i = 1.
答案 1 :(得分:0)
您可能只想使用新的行数进行过滤并重新加载整个表视图。如果最终看不到它们,那么完成所有这些删除动画是没有意义的。或者只是确定哪个部分可见,然后仅加载和删除用户当前可见的那些行?
答案 2 :(得分:0)
我同意@ futureelite7你应该重新加载dataSource而不是操纵视图。我提出了similar question here的解决方案。
基本思想是调用reloadSections:withRowAnimation:并在你的UITableViewDataSource方法中切换分段控件的selectedSegmentIndex。
假设您的数据是平的(只有一个部分),它看起来像这样:
- (IBAction)segmentSwitch:(id)sender
{
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (self.segmentedControl.selectedSegmentIndex)
{
default:
case 0:
return [self.allRows count];
case 1:
return [self.onlySomeRows count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
id data;
switch (self.segmentedControl.selectedSegmentIndex)
{
default:
case 0:
data = [self.allRows objectAtIndex:[indexPath row]];
break;
case 1:
data = [self.onlySomeRows objectAtIndex:[indexPath row]];
break;
}
//TODO: use data to populate and return a UITableViewCell...
}