Reloading a UICollectionView using reloadData meth

2019-01-16 14:54发布

问题:

I need to know when reloading a UICollectionView has completed in order to configure cells afterwards (because I am not the data source for the cells - other wise would have done it already...)

I've tried code such as

[self.collectionView reloadData];
[self configure cells]; // BOOM! cells are nil

I've also tried using

[self.collectionView performBatchUpdates:^{
  [self.collectionView reloadData];
    } completion:^(BOOL finished) {
        // notify that completed and do the configuration now
  }];

but when I reload the data I am getting crashes.

How can I reload the data into the collection, and only when it has finished reloading - do a particular completion handler

回答1:

This is caused by cells being added during layoutSubviews not at reloadData. Since layoutSubviews is performed during next run loop pass after reloadData your cells are empty. Try doing this:

[self.collectionView reloadData];
[self.collectionView layoutIfNeeded];
[self configure cells]; 

I had similar issue and resolved it this way.



回答2:

Collection view is not supported to be reloaded animatedly with help of reloadData. All animations must be performed with methods, such as

[collectionView deleteItemsAtIndexPaths:indexesToDelete];
[collectionView insertSections:sectionsToInsert];
[collectionView reloadItemsAtIndexPaths:fooPaths];

inside of performBatchUpdates: block. That reloadData method can only be used for rough refresh, when all items are removed and laid out again without animation.



回答3:

If you'd like to perform some code after your collectionView has completed it's reloadData() method, then try this (Swift):

    self.collectionView.reloadData()
    self.collectionView.layoutIfNeeded()
    dispatch_async(dispatch_get_main_queue()) { () -> Void in
        // Put the code you want to execute when reloadData is complete in here
    }

The reason this works is because the code within the dispatch block gets put to the back of line (also known as a queue). This means that it is waiting in line for all the main thread operations to finish, including reloadData()'s methods, before it becomes it's turn on the main thread.