7

Ok, więc to, co jest mi potrzebne, aby zapobiec tableview przewijania, gdy nowe elementy dodane powyżej aktualnej widzialnym rzędu. Używam NSFetchedResultsController z dużą ilością obiektów (np. 10 000) i reloadData działa całkiem gładko, gdy nie dotykam contentOffset.Upewnij UITableView utrzymać pozycję przewijania podczas dodawania komórki w górnym

Jednak, gdy staram się manipulować contentOffset utrzymać pozycję przewijania, gdy nowe wpisy są wstawiane zacznie zamarzać UI jak 300 ms, co jest złe dla mnie.

Czy ktoś może zasugerować lepsze (szybsze) rozwiązanie, w jaki sposób utrzymać tableview w tej samej komórce, gdy nowe elementy dodane na górze?

I to jest kod, który używam obecnie śledzić wstawki i przesunięcie contentOffset. Nie obsługuje animacji i różnych rozmiarów komórek.

+0

Czy to działa: migawka 'firstVisibleIndexPath' w" controllerWillChangeContent ". W 'didChangeObject' zachowaj liczbę wierszy wstawionych przed' firstVisibleIndexPath'. Następnie w 'controllerDidChangeContent', obliczyć nowy wiersz (dodając liczbę), ponownie załadować tableView, a następnie' scrollToRowAtIndexPath' do nowej ścieżki indexPath. – pbasdf

+0

upewnij się, że Twój szacowany rozmiar komórek nie jest ustawiony –

Odpowiedz

2

Ok, po kilka odpowiedzi, które wskazał mi w dobrym kierunku wymyśliłem tego rozwiązania. Działa płynnie, ale niektóre brzydkie koordynuje matematykę i nie obsługuje różnych rozmiarów komórek. Mam nadzieję, że będzie to pomocne dla kogoś.

-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
    NSIndexPath *firstVisible = [[self.tableView indexPathsForVisibleRows] firstObject]; 
    self.topVisibleMessage = [self.fetchedResultsController objectAtIndexPath:firstVisible]; 

    NSIndexPath *topIndexPath = [self.fetchedResultsController indexPathForObject:self.topVisibleMessage]; 

    self.cellOffset = self.tableView.contentOffset.y - topIndexPath.row * [self firstRowHeight]; 
} 


-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView reloadData]; 

    if (self.topVisibleMessage) { 
     NSIndexPath *topIndexPath = [self.fetchedResultsController indexPathForObject:self.topVisibleMessage]; 
     CGPoint point = {0, topIndexPath.row * [self firstRowHeight] + self.cellOffset}; 

     [self.tableView setContentOffset:point]; 
    } 
} 
0

Twoje zadanie może być znane z wielu widoków listy aplikacji kanałów informacyjnych. Czy spojrzałeś na te aplikacje? Mogą mieć jakieś rozwiązania. Jak wiem, jedynym sposobem utrzymania pozycji widoku tabeli jest scrollRectToVisible:animated:.

Wiele aplikacji społecznościowy mieć znajomą podejście do wstawiania nowych komórek na górze. Gdy pojawiają się aktualizacje, pojawia się małe powiadomienie na górze widoku z komunikatem ("5 nowych pozycji"), które po dotknięciu wstawia komórki i automatyczne przewijanie do góry.

+0

Myślałem o wizualnym powiadamianiu i dodawaniu komórek po stuknięciu, ale ponieważ używam NSFetchedResultsController, nie mam bezpośredniego dostępu do źródła danych. Jakieś pomysły, jak mogę to zrobić? – kandreych

+0

@kandreych nie używać NSFetchedResultsController może. – Astoria

+0

frc robi naprawdę duże buforowanie tła i synchronizację w mojej aplikacji, ponieważ tak, to w zasadzie czytnik rss, więc naprawdę chcę go zachować. – kandreych