UICollectionView reloadData在iOS 7中无法正常运行

Vap*_*olf 93 ios uicollectionview ios7

我一直在更新我的应用程序以在iOS 7上运行,这在大多数情况下都很顺利.我已经注意到在一个以上的应用程序中,a的reloadData方法UICollectionViewController并不像以前那样.

我将加载UICollectionViewController,UICollectionView正常填充一些数据.这在第一次很好用.但是,如果我请求新数据(填充UICollectionViewDataSource),然后调用reloadData,它将查询数据源numberOfItemsInSectionnumberOfSectionsInCollectionView,但它似乎没有调用cellForItemAtIndexPath正确的次数.

如果我将代码更改为仅重新加载一个部分,那么它将正常运行.这对我来说没有问题,但我认为不应该这样做.reloadData应根据文档重新加载所有可见的单元格.

有没有人见过这个?

小智 71

在主线程上强制执行此操作:

dispatch_async(dispatch_get_main_queue(), ^ {
    [self.collectionView reloadData];
});
Run Code Online (Sandbox Code Playgroud)

  • 从主队列调度主队列只会延迟执行直到下一个运行循环,允许当前排队的所有内容首先执行. (7认同)
  • 它没有那么多意义,因为你不能从主线程调用reloadData(你不能更新主线程中的视图)所以这可能是一个副作用,导致你想要的由于一些竞争条件. (6认同)
  • 谢谢!!仍然不明白Joony论证是否正确,因为核心数据请求消耗它的时间并且它的答案被延迟或因为我正在willDisplayCell重新加载数据. (2认同)

lia*_*ols 63

在我的例子中,数据源中的单元格/节的数量从未改变,我只是想重新加载屏幕上的可见内容.

我设法通过调用来解决这个问题:

[self.collectionView reloadItemsAtIndexPaths:[self.collectionView indexPathsForVisibleItems]];
Run Code Online (Sandbox Code Playgroud)

然后:

[self.collectionView reloadData];
Run Code Online (Sandbox Code Playgroud)

  • 该行导致我的应用程序崩溃 - "***断言失败 - [UICollectionView _endItemAnimations],/ SourceCache/UIKit_Sim/UIKit-2935.137/UICollectionView.m:3840" (6认同)
  • 这个bug纯属胡说八道!当我重新加载我的 collectionView 时,我所有的单元格 - 随机 - 消失了,只有当我的集合中有一种特定类型的单元格时。我失去了两天,因为我无法理解发生了什么,现在我应用了你的解决方案并且它有效,我仍然不明白为什么它现在有效。这太令人沮丧了!无论如何,感谢您的帮助 :D !! (2认同)

Ant*_*sov 26

我有完全相同的问题,但我设法找到了错误的原因.在我的情况下,我从collectionView:cellForItemAtIndexPath调用reloadData :看起来不正确.

reloadData调用调用到主队列一次又一次地修复了问题.

  dispatch_async(dispatch_get_main_queue(), ^{
    [self.collectionView reloadData];
  });
Run Code Online (Sandbox Code Playgroud)


小智 20

重新加载一些项目对我不起作用.在我的情况下,只是因为我正在使用的collectionView只有一个部分,我只是重新加载该特定部分.这次正确地重新加载内容.很奇怪,这只发生在iOS 7(7.0.3)上

[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
Run Code Online (Sandbox Code Playgroud)


dim*_*iax 12

斯威夫特4 - 3

// GCD    
DispatchQueue.main.async(execute: collectionView.reloadData)

// Operation
OperationQueue.main.addOperation(collectionView.reloadData)
Run Code Online (Sandbox Code Playgroud)

斯威夫特2

// Operation
NSOperationQueue.mainQueue().addOperationWithBlock(collectionView.reloadData)
Run Code Online (Sandbox Code Playgroud)


小智 11

我在iOS 7上遇到了与reloadData相同的问题.经过长时间的调试,我发现了问题.

在iOS7上,UICollectionView上的reloadData不会取消之前尚未完成的更新(在performBatchUpdates:block中调用的更新).

解决此错误的最佳解决方案是停止当前处理的所有更新并调用reloadData.我没有找到取消或停止performBatchUpdates块的方法.因此,为了解决这个问题,我保存了一个标志,指示是否存在当前正在处理的performBatchUpdates块.如果没有当前处理的更新块,我可以立即调用reloadData,一切都按预期工作.如果有一个当前正在处理的更新块,我将在performBatchUpdates的完整块上调用reloadData.