2011-09-20 17 views
9

Próbuję utworzyć UITableView z datami, nie powinno być bardzo ekscytujące, wiem. Zaczyna się około bieżącej daty, ale użytkownik powinien móc przewinąć w dół (przyszłość) i do góry (przeszłość), o ile chce. Powoduje to potencjalnie nieskończoną liczbę wierszy. Więc jaki jest sposób, aby go utworzyć?Wieczne przewijanie UITableView

Wracając NSIntegerMax jak liczba wierszy już awarii aplikacji, ale nawet jeśli nie, to nadal nie uwzględnia możliwość przewijania się. Mógłbym zacząć w połowie drogi, ale w końcu jest maksimum.

Wszelkie pomysły, jak to zrobić lub podrobić to? Czy mogę zaktualizować/odświeżyć tabelę w jakiś sposób, bez zauważania przez użytkownika, więc nigdy nie natknę się na granicę?

ROZWIĄZANIE:
poszedłem z sugestią @ Endera i wykonany stół o stałej wysokości komórek. Ale zamiast przeładować, gdy użytkownik przewinie się do krawędzi zblokowanych komórek, przeładowałem stół, gdy przewijanie zatrzyma się. Aby zmieścić się z użytkownikiem przewijającym duże odległości bez zatrzymywania, po prostu zwiększyłem liczbę wierszy do 1000, ustawiając stałą ROW_CENTER na 500. Jest to metoda, która zajmuje się aktualizowaniem wierszy.

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{ 
    NSArray *visible = [self.tableView indexPathsForVisibleRows]; 
    NSIndexPath *upper = [visible objectAtIndex:0]; 
    NSIndexPath *lower = [visible lastObject]; 

    // adjust the table to compensate for the up- or downward scrolling 
    NSInteger upperDiff = ROW_CENTER - upper.row; 
    NSInteger lowerDiff = lower.row - ROW_CENTER; 

    // the greater difference marks the direction we need to compensate 
    NSInteger magnitude = (lowerDiff > upperDiff) ? lowerDiff : -upperDiff; 

    self.offset += magnitude; 
    CGFloat height = [self tableView:self.tableView heightForRowAtIndexPath:lower]; 
    CGPoint current = self.tableView.contentOffset; 
    current.y -= magnitude * height; 
    [self.tableView setContentOffset:current animated:NO]; 

    NSIndexPath *selection = [self.tableView indexPathForSelectedRow]; 
    [self.tableView reloadData]; 
    if (selection) 
    { 
     // reselect a prior selected cell after the reload. 
     selection = [NSIndexPath indexPathForRow:selection.row - magnitude inSection:selection.section]; 
     [self.tableView selectRowAtIndexPath:selection animated:NO scrollPosition:UITableViewScrollPositionNone]; 
    } 
} 

Magiczne przerwy, gdy użytkownik przewija do krawędzi stołu bez zatrzymywania się, ale z widoku tabeli bounces nieruchomość niepełnosprawnej, to po prostu czuje się jak drobne usterki, ale całkowicie do przyjęcia. Jak zwykle dzięki StackOverflow!

+0

Proszę wypróbować kod w mojej odpowiedzi poniżej. Używa prostej logiki. –

Odpowiedz

5

Powinieneś ustalić stałą liczbę komórek i dostosować źródło danych, gdy użytkownik przewinie się w pobliżu końca widoku tabeli. Na przykład masz tablicę z 51 datami (dziś, 25 przyszłych i 25 przeszłych). Gdy aplikacja próbuje uczynić komórkę pobliżu jednego z granic, ponownie skonfigurować tablicę i nazywają reloadData

+0

Dzięki za sugestię. Próbuję teraz, ale wywołanie reloadData nie zmieni pozycji przewijania (lub contentOffset) widoku tabeli, więc przestaje się przewijać. Jaki był twój pomysł? Twoje zdrowie. – epologee

+0

Obawiam się, że nie ma możliwości ponownego załadowania danych bez zatrzymywania przewijania. Może ręczne ustawienie contentOffset widoku table dla bieżącej komórki po wywołaniu reloadData ... – ender

+0

Wybrałem twoje rozwiązanie, ale przeładuj ponownie w metodzie 'scrollViewDidEndDecelerating:'. W ten sposób przeładowanie nie zostanie zauważone przez użytkownika. Zwiększenie liczby wierszy do prawdopodobnego wysokiego numeru (np. 1000) zajmie się większością przypadków użycia, nie zauważając żadnych zakłóceń. Dzięki! – epologee

2

Dwie myśli:

  1. Czy naprawdę potrzebują UITableView? Możesz użyć ekranu o rozmiarze: UIScrollView, o wysokości trzech ekranów. Po osiągnięciu końca przewijania ułóż treść i dostosuj pozycję przewijania. Daje to złudzenie nieskończonego przewijania. Tworzenie etykiet daty i układanie ich w layoutSubviews: nie powinno być zbyt dużym wysiłkiem.

  2. Jeśli naprawdę chcesz pozostać przy UITableView, możesz pomyśleć o posiadaniu dwóch UITableViews. Jeśli przewijanie w pierwszym osiągnie punkt krytyczny, wywinąć wątek i wypełnić drugi. Następnie w pewnym momencie wymień widoki i uruchom przewijanie ręcznie, aby użytkownik nie odnotował zmiany. To tylko pomysł z mojej głowy. Jeszcze nie zaimplementowałem czegoś podobnego, ale zaimplementowałem nieskończony UIScrollView.

+0

Dobre sugestie. Sam zastanawiałem się nad pierwszym, ale chciałem trzymać się UITableView z powodu ponownego użycia komórki i faktu, że wydaje się, że powinien to być stół: S. Wypróbuję UIScrollView, aby zobaczyć, jak dobrze się trzyma. Dzięki! – epologee

3

Można też spojrzeć na „Zaawansowane techniki” Scroll Zobacz Dyskusja na WWDC 2011. Oni pokazali, jak można stworzyć UIScrollView która przewija się w nieskończoność. Zaczyna się około 5 minut. w.

+0

Dzięki, dobra wskazówka, mam gdzieś buforowane. Och i wielkie dzięki za Trazzle, używał go od lat! – epologee

0

odpowiedziałem na to pytanie w innym poście: https://stackoverflow.com/a/15305937/2030823

obejmują:

https://github.com/samvermette/SVPullToRefresh

SVPullToRefresh obsługuje logikę kiedy UITableView osiągnie dno. Przędza zostanie pokazana automatycznie i uruchomiony zostanie blok wywołania zwrotnego. Dodajesz logikę biznesową do bloku oddzwaniania.

#import "UIScrollView+SVInfiniteScrolling.h" 

// ... 

[tableView addInfiniteScrollingWithActionHandler:^{ 
    // append data to data source, insert new cells at the end of table view 
    // call [tableView.infiniteScrollingView stopAnimating] when done 
}]; 
0

To pytanie zostało już zadane: implementing a cyclic UITableView mam kopiując tą odpowiedź tutaj, aby ułatwić ponieważ Pytający nie spełniło moją odpowiedź.

UITableView jest taki sam jak UIScrollView w metodzie scrollViewDidScroll.

Łatwo jest naśladować nieskończone przewijanie.

  1. podwójnego układu, aby głowy i ogona są połączone ze sobą w celu naśladowania okrągłego stołu

  2. używać następujący kod do użytkownika przełącznik od 1 części dwukrotnie tabeli i 2 części dwukrotnie tabeli, gdy mają one skłonność aby dotrzeć do początku lub końca stołu.

:

/* To emulate infinite scrolling... 

The table data was doubled to join the head and tail: (suppose table had 1,2,3,4) 
1 2 3 4|1 2 3 4 (actual data doubled) 
--------------- 
1 2 3 4 5 6 7 8 (visualizing joined table in eight parts) 

When the user scrolls backwards to 1/8th of the joined table, user is actually at the 1/4th of actual data, so we scroll instantly (we take user) to the 5/8th of the joined table where the cells are exactly the same. 

Similarly, when user scrolls to 6/8th of the table, we will scroll back to 2/8th where the cells are same. (I'm using 6/8th when 7/8th sound more logical because 6/8th is good for small tables.) 

In simple words, when user reaches 1/4th of the first half of table, we scroll to 1/4th of the second half, when he reaches 2/4th of the second half of table, we scroll to the 2/4 of first half. This is done simply by subtracting OR adding half the length of the new/joined table. 

Written and posted by Anup Kattel. Feel free to use this code. Please keep these comments if you don't mind. 
*/ 


-(void)scrollViewDidScroll:(UIScrollView *)scrollView_ 
{ 

    CGFloat currentOffsetX = scrollView_.contentOffset.x; 
    CGFloat currentOffSetY = scrollView_.contentOffset.y; 
    CGFloat contentHeight = scrollView_.contentSize.height; 

    if (currentOffSetY < (contentHeight/8.0)) { 
    scrollView_.contentOffset = CGPointMake(currentOffsetX,(currentOffSetY + (contentHeight/2))); 
    } 
    if (currentOffSetY > ((contentHeight * 6)/ 8.0)) { 
     scrollView_.contentOffset = CGPointMake(currentOffsetX,(currentOffSetY - (contentHeight/2))); 
    } 

} 

PS: - Użyłem tego kodu w jednej z moich aplikacji o nazwie NT Time Table (Lite). Jeśli chcesz podgląd, możesz sprawdzić aplikację: https://itunes.apple.com/au/app/nt-time-table-lite/id528213278?mt=8

Jeśli Twoja tabela może czasami być za krótka, na początku powyższej metody możesz dodać logikę, aby zakończyć, gdy liczba danych jest wyrażona np. Mniej niż 9.

Powiązane problemy