【问题标题】:Reloading a UICollectionView using reloadData method returns immediately before reloading data使用 reloadData 方法重新加载 UICollectionView 会在重新加载数据之前立即返回
【发布时间】:2013-08-14 11:48:36
【问题描述】:

我需要知道何时重新加载 UICollectionView 以便之后配置单元格(因为我不是单元格的数据源 - 否则已经完成了......)

我尝试过诸如

之类的代码
[self.collectionView reloadData];
[self configure cells]; // BOOM! cells are nil

我也尝试过使用

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

但是当我重新加载数据时,我遇到了崩溃。

如何将数据重新加载到集合中,并且仅在完成重新加载后 - 执行特定的完成处理程序

【问题讨论】:

  • 我想我遇到了类似的问题。问题是在下一次运行循环传递期间发生的 layoutSubview 期间加载了单元格。不幸的是我还没有找到解决方案。我想知道为什么 UICollectionViewDelegate 没有像这样的方法: - collectionView:willBeginDisplayingCell:forItemAtIndexPath: 虽然有: - collectionView:didEndDisplayingCell:forItemAtIndexPath: 你已经解决了吗?
  • 发生的情况是批量更新块希望您调用添加和删除与重新加载期间发生的新行数和节数相对应的行/节。如果这没有发生,则抛出一个断言。

标签: objective-c-blocks uicollectionview uicollectionviewcell completionhandler


【解决方案1】:

这是由于在 layoutSubviews 期间添加的单元格不是在 reloadData 处。由于 layoutSubviews 在 reloadData 之后的下一个运行循环传递期间执行,因此您的单元格为空。 尝试这样做:

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

我有类似的问题,并以这种方式解决。

【讨论】:

  • 我遇到了这个确切的问题,在调用 -reloadDatavisibleCells 为 0。调用 -layoutIfNeeded 解决了这个问题。 lukewar 的回答应该被接受。
  • 我想补充一点,这个解决方案在强制集合视图同步重新加载方面非常有用,以防您从核心数据进行异步更新,从而解决了巨大的麻烦和崩溃问题。
  • 如果你想保证布局周期,你应该调用setNeedsLayout然后layoutIfNeeded
  • 但是为什么单元格会在这些周期中加载,我以前从未遇到过很多 UICollectionView 的这些问题,直到现在。
【解决方案2】:

如果你想在你的 collectionView 完成它的 reloadData() 方法后执行一些代码,那么试试这个 (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
    }

之所以可行,是因为调度块中的代码被放到了行的后面(也称为队列)。这意味着它正在排队等待所有主线程操作完成,包括 reloadData() 的方法,然后才打开主线程。

【讨论】:

  • 好吧,这并不完全正确,调度块可能会插入一些主线程操作之间,请参阅stackoverflow.com/a/10450867/4003774。但是由于 layoutIfNeeded,您的代码将可以工作(即使没有 dispatch_async)(请参阅@lukewar 的答案)
【解决方案3】:

不支持在reloadData 的帮助下以动画方式重新加载集合视图。所有的动画都必须用方法来执行,比如

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

performBatchUpdates: 块内。 reloadData 方法只能用于粗略刷新,当所有项目都被移除并重新布局时,没有动画。

【讨论】:

  • 我在拉动刷新和 api 响应之间进行了竞赛,这很有帮助。我只是删除并插入我想要重新加载的部分而不是 reloadData:self.collectionView?.performBatchUpdates({ self.collectionView?.deleteSections(IndexSet(arrayLiteral: 0)) self.collectionView?.insertSections(IndexSet(arrayLiteral: 0)) }, completion: nil)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多