iOSで、UITableViewにサーバーからとってきた画像を表示させることはよくあると思います。
サーバーから画像を取得して表示するのにAsyncImageViewをよく使うのですが、TableViewをスクロールしたときにCellがリサイクルされるようにしていると、一瞬リサイクルされる前の画像が表示されてしまう、ということがおきます。

これに対しては、CellがリサイクルされるときにUIImageにnilをいれておく、というのが定石なのですが、すると次はスクロールしてるときに画像がチラついてしまう、ということがおきました。

TableViewを下いっぱいまでスクロールして、びよーんってやってるときとか顕著にみれるのですが、これは画面上は同じCellが表示され続けているけど、TableViewがスクロールされるのでCellのリサイクルが起きていて、一回imageにnilがいれられてからキャッシュされている画像をいれなおす、ということが行われているため、一瞬画像が消えてしまいチラついてしまうっぽいです。

なので、新たにサーバーから画像を読み込むときはUIImageにnilをいれて、既に画像が読み込まれてキャッシュされているときはnilをいれない、というように実装することでうまく表示できました!

以下、サンプルコードです。

static NSString *CellIdentifier = @"Cell";

HogeCellView *cell = (HogeCellView *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[NSBundle mainBundle] loadNibNamed:@"HogeCell" owner:self options:nil] objectAtIndex:0];
}else{
    // リサイクルしてる
    if(![[AsyncImageLoader sharedLoader].cache objectForKey:[NSURL URLWithString:thumb_url]]){
        // キャッシュされていない
        cell.thumbImageView.image = nil;
    }
}

8行目で、AsyncImageLoaderから、読み込もうとしているURLの画像が既にキャッシュされているかどうかをみて、キャッシュされていないときだけnilをいれるようにしています。

Leave a Reply