【发布时间】:2015-01-19 11:21:46
【问题描述】:
好的,所以我需要在当前可见行上方添加新元素时防止 tableview 滚动。我将 NSFetchedResultsController 与很多对象(如 10 000)一起使用,当我不接触 contentOffset 时,reloadData 工作得非常顺利。
但是,当我尝试操作 contentOffset 以在插入新条目时保持滚动位置时,它开始冻结 UI 大约 300 毫秒,这对我不利。
当新项目添加到顶部时,任何人都可以提出更好(更快)的解决方案吗?
这是我目前用来跟踪插入和移动 contentOffset 的代码。它不支持动画和不同的单元格大小。
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
switch(type) {
case NSFetchedResultsChangeInsert:
[_insertions addObject:@(newIndexPath.row)];
break;
}
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
_insertions = @[].mutableCopy;
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
NSMutableArray *copy = _insertions.mutableCopy;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSSortDescriptor *lowestToHighest = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES];
[copy sortUsingDescriptors:[NSArray arrayWithObject:lowestToHighest]];
dispatch_sync(dispatch_get_main_queue(), ^{
for (NSNumber *i in copy) {
[self p_delayedAddRowAtIndex:[i integerValue]];
}
[self.tableView reloadData];
});
});
}
- (CGFloat)p_firstRowHeight {
return [self tableView:[self tableView] heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0
inSection:0]];
}
-(void)p_delayedAddRowAtIndex:(NSInteger)row {
NSIndexPath *firstVisibleIndexPath = [[self.tableView indexPathsForVisibleRows] firstObject];
if (firstVisibleIndexPath.row >= row) {
CGPoint offset = [[self tableView] contentOffset];
offset.y += [self firstRowHeight];
if ([self.tableView visibleCells].count > self.tableView.frame.size.height / [self firstRowHeight]) {
[[self tableView] setContentOffset:offset];
}
}
}
【问题讨论】:
-
这项工作是否可行:快照
firstVisibleIndexPathincontrollerWillChangeContent。在didChangeObject中,记录在firstVisibleIndexPath之前插入的行数。然后在controllerDidChangeContent中,计算新行(通过添加计数),重新加载tableView,然后scrollToRowAtIndexPath到新的indexPath。 -
确保未设置估计的单元格大小
标签: ios objective-c uitableview core-data nsfetchedresultscontroller