LoginSignup
24
24

More than 5 years have passed since last update.

UITableView / UICollectionView の reloadData が完了した直後にセルを参照したい

Last updated at Posted at 2015-06-29

 UITableView や UICollectionView の reloadData を実行した時点ではまだセルのレイアウトが完了していないことがあります。

-visibleCells
[tableView reloadData];
NSArray *cells = [tableView visibleCells];
-indexPathsForVisibleItems
[collectionView reloadData];
NSArray *indexPaths = [collectionView indexPathsForVisibleItems];

 このときの cells, indexPaths には reloadData で反映する前のセルやインデックス、もしくは nil が返ってくることがあります。それだと困るので、reloadData が完了した後でセルやインデックスを参照できるようにするために強制レイアウトを実行します。

-layoutSubviews
[tableView reloadData];
[tableView layoutIfNeeded];
NSArray *cells = [tableView visibleCells];

 強制レイアウトでは layoutSubviews ではなく layoutIfNeeded を使用します※。これで reloadData で反映したセルがおそらく得られるかと思いますが、手元で検証したところ、これでもうまくいかない場合があるようです。なので代わりに GCD で対応します。

dispatch_async()
[tableView reloadData];

dispatch_async(dispatch_get_main_queue(), ^{
    NSArray *cells = [tableView visibleCells];
});

UIView Class Reference – layoutSubviews

layoutSubviews
~
You should not call this method directly. If you want to force a layout update, call the setNeedsLayout method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded method.

24
24
3

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
24
24