UICollectionView received layout attributes for a cell with an index path that does not exist

我们的项目中有一个相对复杂的页面,如下图


IMG_0001.PNG

我的处理方式是将整个下部写成一个UICollectionView,“单选题 本大题共。。。”和“算法的。。”作为cell,其他元素作为header和footer。由于下方淡蓝色的cell宽度是自适应的,逻辑是cell的宽度根据cell的内容来自适应,并且不能超过一定数值,否则lable添加“...”。
这个需求很快就想到了使用Autolayout的自适应Cell,我们只要设定好cell的约束,其他的布局就交给Autolayout来做。

let flowLayout = UICollectionViewLeftAlignedLayout()
flowLayout.estimatedItemSize = CGSize(width: 125, height: 40)
self.collectionView.collectionViewLayout = flowLayout

这个页面上面有左右切换按钮,点击之后会刷新UICollectionView的数据。进入页面没有问题,但是切换数据,调用ReloaData()方法就会崩溃,崩溃信息为:
UICollectionView received layout attributes for a cell with an index path that does not exist
找了很久,没有找到解决的办法,但大概的原因可能是:
使用了Autolayout自适应Cell后,UICollectionView会自动生成相应cell的size,并缓存起来(重点)。当我们获取了新的数据并ReloaData后,UICollectionView会尝试去拿缓存起来的cell的size(目的是提高性能)。但是此时我们的数据源发生了改变,cell的个数也变了,因此出现了数组下标越界,也就崩溃了。
正确的方法是:

self.collectionView.reloadData()
self.collectionView.collectionViewLayout.invalidateLayout()

刷新数据后清空collectionViewLayout的缓存,让Autolayout重新计算UICollectionView的cell的size。这样就没有问题了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,222评论 4 61
  • 其中随开机启动的设置很实用 如果选择远程配置 就不要做二次加工的事情。
    黑涩布朗尼阅读 1,105评论 0 0
  • 823fdd1d51c4阅读 708评论 0 1
  • 摄影 杨泽平 背景是迎风飘扬的五星红旗,主角是一只动作夸张的小麻雀,它张大嘴,俯下身子,像是歌星正在深情歌唱。让摄...
    窗外白杨阅读 2,649评论 5 5
  • 与对企业自身有利的成员利益合作经营是一种应对挑战和寻求突破性发展的解决方式和战略。一个企业不可能为所有人提供全部产...
    HR马阅读 3,196评论 0 0