web-dev-qa-db-ja.com

UITableView scrollToRowAtIndexPath

テーブルビューに最後の位置を記憶させようとしています。これにより、アプリを再度実行した後、その位置までスクロールします。これを行うには、_viewWillDisappear:_メソッドで、最初に表示される行番号を取得し、それをNSUserDefaultsに保存します。次に、viewDidAppearで、scrollToRowAtIndexPathをテーブルビューに送信して、その行までスクロールしようとします。ただし、NSRangeExceptionを取得します:

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

助けていただければ幸いです。コードは次のとおりです。

_- (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"];
}
_
20
Ali Shafai

ScrollToRowAtIndexPathを呼び出す前に、TableViewデータをリロードします。

[contentTableView reloadData];
53
William Rust

ContentTableViewがまだデータのロードを完了していない可能性があります。

8
user121301

DyingCactusの答えについて詳しく説明したいと思います。私はかなり新しいiOS開発者であり、私の状況は少し異なっていましたが、彼が言ったように

「contentTableViewがまだデータのロードを完了していない可能性があります」

答えは簡単でしたが、それは私の車輪を回しました、そしてそれはまさに私のために起こっていたものでした。

私の設定

  • UITableViewはViewController "A"上にあります
  • 私のアプリは新しいViewController「B」を提示します
  • ViewController "B"でボタンをクリックすると、UITableViewのデータソースにデータが追加されます。
  • Bのボタンクリックハンドラーから、[tableView reloadData]と呼ばれる
  • Bのボタンクリックハンドラーから、[tableView selectRowAtIndexPath:idxPath animated:false scrollPosition:UITableViewScrollPositionTop];と呼ばれる
  • ViewController "B"が閉じられ、 "A"が再度表示されます(更新されたUITableViewが表示されます)

解決策

  • 私が修正しなければならなかった最初の問題は、メインスレッドでreloadDataを呼び出すことでした。

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

  • 最後の問題は、waitUntilDonetrue(DUH!)に変更することでした。

ええ、明らかに私にとっては、メインスレッドで実行されているreloadData呼び出しがセレクターが完了するまでブロックに明示的に設定されていなかったため、contentTableViewはデータのロードを完了しませんでした。

これが誰かを助けることを願っています。

0
C. Tewalt