详解ios监听reloadData刷新列表完毕的时机

2020-01-21 07:40:52王旭

分析:

reloadData 是一个异步方法,并不会等待 UITableView 或者 UICollectionView (后面统称 listView )真正刷新完毕后才执行后续代码,而是立即执行后续代码。我们执行 reloadData 的本意是刷新 listView ,随后会进入一系列的DataSource和Delegate回调,有些是和reloadData同步发生的,有些是异步发生的。

  • 同步: numberOfSectionsInCollectionView 和 numberOfItemsInSection
  • 异步: cellForItemAtIndexPath
  • 同步+异步: sizeForItemAtIndexPath

    问题:

    由于cell复用的原因,直接在 reloadData 后执行代码是有可能出问题的。比如在 reloadData 前保留了一个cell,在 reloadData 后,对这个cell(已经不是原来的cell了)进行某些操作,会出现一些异常问题。

    解决办法:

    在 reloadData 前不是保留cell,二是保留当前cell对应的 NSIndexPath ,然后在 reloadData 完毕( listView 真正刷新完毕)后通过方法 cellForItemAtIndexPath: 重新获取cell,然后进行相应的操作。

    获取listView真正刷新完毕的时机的几种方法

    方法1、通过layoutIfNeeded方法,强制重绘并等待完成。

    
    [self.collectionView reloadData];
    [self.collectionView layoutIfNeeded];
    // 刷新完成,执行后续需要执行的代码
    if ( self.didPlayIdx ) {
      MyCell* cell = (MyCell*)[self.collectionView cellForItemAtIndexPath:self.didPlayIdx];
      if (cell) {
     [cell playWithPlayer:self.player];
      }
    }