UITableView や UICollectionView の reloadData
を実行した時点ではまだセルのレイアウトが完了していないことがあります。
[tableView reloadData];
NSArray *cells = [tableView visibleCells];
[collectionView reloadData];
NSArray *indexPaths = [collectionView indexPathsForVisibleItems];
このときの cells
, indexPaths
には reloadData で反映する前のセルやインデックス、もしくは nil が返ってくることがあります。それだと困るので、reloadData が完了した後でセルやインデックスを参照できるようにするために強制レイアウトを実行します。
[tableView reloadData];
[tableView layoutIfNeeded];
NSArray *cells = [tableView visibleCells];
強制レイアウトでは layoutSubviews
ではなく layoutIfNeeded
を使用します※。これで reloadData で反映したセルがおそらく得られるかと思いますが、手元で検証したところ、これでもうまくいかない場合があるようです。なので代わりに GCD で対応します。
[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.