Ok, quindi quello che mi serve è di impedire lo scrolling di tableview quando nuovi elementi vengono aggiunti al di sopra della riga visibile corrente. Sto usando NSFetchedResultsController con molti oggetti (come 10.000) e reloadData funziona abbastanza bene quando non sto toccando contentOffset.Rendi UITableView in posizione di scorrimento quando aggiungi le celle in cima
Tuttavia, quando sto cercando di manipolare contentOffset per mantenere la posizione di scorrimento quando vengono inserite nuove voci, inizia a bloccare l'interfaccia utente per 300 ms, il che non va bene per me.
Qualcuno può suggerire una soluzione migliore (più veloce) su come mantenere tableview nella stessa cella quando vengono aggiunti nuovi elementi nella parte superiore?
E questo è il codice che sto usando attualmente per tracciare inserimenti e spostare contenutiOffset. Non supporta animazioni e diverse dimensioni della cella.
- (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];
}
}
}
Questo lavoro: istantanea 'firstVisibleIndexPath' in' controllerWillChangeContent'. In 'didChangeObject', tieni un conteggio del numero di righe inserite prima di' firstVisibleIndexPath'. Quindi in 'controllerDidChangeContent', calcola la nuova riga (aggiungendo il conteggio), ricarica la tabellaView e poi' scrollToRowAtIndexPath' nel nuovo indexPath. – pbasdf
assicurati che la dimensione stimata delle celle non sia impostata –