LoginSignup
35
36

More than 5 years have passed since last update.

scrollViewDidScroll:で都度、追加の読み込みをする

Last updated at Posted at 2014-10-19

テーブルビューを一番したまでスクロールさせると、勝手に数件分のデータを読み込み表示してくれる機能を実装したかった。
scrollViewDidScroll:メソッドが想像以上に呼び出されるので、無駄な呼び出しをあの手この手で削ぎ落としていくのに頭を使った。
その部分に関してメモを残す。

やりたいこと(仕様)

  • UITableViewが下端までスクロールされたら(バウンス)、追加でn件分のデータを読み込んで表示したい。
  • 読み込んだ後のセルの表示位置はそのままにしておき、テーブルビューの1行目に行ったりしない。

アプローチ

  1. UIScrollViewControllerのデリゲートメソッドscrollViewDidScroll:を使う
  2. このメソッドは頻繁に呼びだされるのでバウンスされたときという条件を絞り込む
  3. バウンスされたときという条件下でも何度も呼び出されるので、実装を非同期実行・並列処理として不要な呼び出しをキャンセルする

サンプルコード

該当のビューコントローラにて
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

    //バウンスの判定条件は、テーブルビューのサイズを超えて一番したまでスクロールされ、かつそれが ユーザの動作によって行われている場合とする
    BOOL isBouncing = NO;
    isBouncing = (self.tableView.contentOffset.y >= (self.tableView.contentSize.height - self.tableView.bounds.size.height)) &  self.tableView.dragging;
    if(isBouncing)
    {
        //どれか一つのスレッドが処理中なら、ほかのスレッドの処理は中断する。
        if (self.isUpdating) { // isUpdating は このメソッドの処理が実行中かどうかを知らせる BOOL 値のプロパティ
            return;
        }
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            self.isUpdating = YES;

            /*
             * 追加でn件分のデータを読み込む処理
             */

            //処理が1秒続いたとする
            [NSThread sleepForTimeInterval:1.0];

            self.isUpdating = NO;
        });
    }
}

結果

上のコードを活用することで、やりたいことは実現できた。
その上で記載すべきこととしては2点。

1. EXC_BAD_ACCESS が出た

追加のデータを表示させた後に、このビューコントローラからひとつ前のビューコントローラに戻ると発生した。
[XCode]ARC使用中にエラー「EXC_BAD_ACCESS」「respondsToSelector」が出た場合の対処法」を参照させていただいたところ、テーブルビューのdelegateを解放していないことが原因ということがわかった。そのため、deallocメソッドをオーバライドした。

該当のビューコントローラにて
- (void)dealloc
{
    self.tableView.delegate = nil;
}

2. reloadDataの利用で表示はうまくいくか?

サンプルコードはないが、テーブルビューの更新はreloadDataを使っている。これを使うと一律でテーブルビューが常に1行目を表示してしまうようだと困ったのだが、そんなことはなかった。

35
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
36