2009-09-26 13 views
19

Próbuję ustawić widok tabeli jako ostatnią pozycję, aby po ponownym uruchomieniu aplikacji przewinąć do tej pozycji. aby to zrobić, w metodzie viewWillDisappear: otrzymuję pierwszy widoczny numer wiersza i zapisuję go na NSUserDefaults. następnie w moim widokuDidAppear próbuję przewinąć do tego wiersza, wysyłając scrollToRowAtIndexPath do widoku tabeli. Jednak dostaję NSRangeException:UITableView scrollToRowAtIndexPath

*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[UITableView scrollToRowAtIndexPath:atScrollPosition:animated:]: section (0) beyond bounds (0).

Każda pomoc mile widziana. Oto kod:

- (void)viewDidAppear:(BOOL)animated 
{ 
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 

    if ([userDefaults valueForKey:@"content_row"] != nil) 
    { 
     int rowToHighlight = [[userDefaults valueForKey:@"content_row"] intValue]; 
     NSIndexPath * ndxPath= [NSIndexPath indexPathForRow:rowToHighlight inSection:0]; 
     [contentTableView scrollToRowAtIndexPath:ndxPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
    } 
} 

-(void) viewWillDisappear:(BOOL)animated 
{ 
    NSIndexPath *selectedRowPath = [[contentTableView indexPathsForVisibleRows] objectAtIndex:0]; 
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
    [userDefaults setInteger:selectedRowPath.row forKey:@"content_row"]; 
} 
+0

Czy możesz opublikować fragment kodu, który wykonuje tworzenie scrollToRowAtIndexPath i NSIndexPath? – probablyCorey

Odpowiedz

52

Ponownie załaduj dane TableView przed wywołaniem scrollToRowAtIndexPath.

[contentTableView reloadData]; 
+4

To nie działa dla mnie, gdy dane nie są jeszcze załadowane (przy użyciu pobranego kontrolera wyników). Moim rozwiązaniem było sprawdzenie najpierw 'tableView.numberOfRowsInSection (0)> 0'. – SimplGy

+0

lub w innym wątku, spróbuj tego. '[tblView performSelectorOnMainThread: @selector (reloadData) withObject: nil waitUntilDone: YES]' – matrixugly

8

Jest możliwe, że contentTableView nie zakończył jeszcze ładowania danych.

+1

Jak otrzymam powiadomienie po zakończeniu? –

+2

Niestety, myślałem, że scrollToRowAtIndexPath został wywołany w viewDidLoad. Mam podobne wywołania w viewDidAppear, ale zamiast wracać do zapisanego numeru wiersza, wracam do zapisanej wartości klucza, która jest zapisywana w didSelectRowAtIndexPath. Przed wywołaniem scrollToRowAtIndexPath znajduję wiersz klucza wartości w aktualnie załadowanym źródle danych. – DyingCactus

+0

Słodki! To faktycznie pomogło mi w obracaniu się moich narzędzi we właściwym kierunku. Opracowałem w osobnej odpowiedzi. – matrixugly

0

Chciałbym rozwinąć odpowiedź DyingCactus. Jestem całkiem nowy iOS programista i moja sytuacja była trochę inna, ale jak powiedział

„Jest możliwe, że contentTableView jeszcze nie gotowy do załadunku danych”

Chociaż odpowiedź był krótki, obracał moje koła i właśnie to działo się dla mnie.

Moja konfiguracja

  • UITableView jest ViewController "A"
  • Moja aplikacja prezentuje
  • Na ViewController "B" kliknięciu przycisku, a następnie dane są dodawane nowe ViewController "B" do źródła danych dla UITableView.
  • Od przycisk click obsługi B., [tableView reloadData] nazywa
  • Od przycisk click obsługi B., [tableView selectRowAtIndexPath:idxPath animated:false scrollPosition:UITableViewScrollPositionTop]; nazywa
  • ViewController "B" zostaje odrzucona i "A" przedstawia kolejny (widocznych zaktualizowaną UITableView)

Rozwiązanie

  • pierwszy problem miałem naprawić było zadzwonić reloadData w głównym wątku jak w przykładzie

    [tblView performSelectorOnMainThread: @selector (reloadData) withObject: zerowe waitUntilDone false];

  • Ostatnim problemem była zmiana waitUntilDone na true (DUH!)

Tak, tak, oczywiście dla mnie, contentTableView nie zostało zrobione ładowania danych, ponieważ moje wezwanie reloadData który prowadzony jest w głównym wątku nie został jawnie ustawić blokowanie aż selektor zostało zrobione.

Mam nadzieję, że to komuś pomaga.