我們的項(xiàng)目中有一個(gè)相對(duì)復(fù)雜的頁(yè)面,如下圖
我的處理方式是將整個(gè)下部寫成一個(gè)UICollectionView,“單選題 本大題共。。?!焙汀八惴ǖ摹??!弊鳛閏ell,其他元素作為header和footer。由于下方淡藍(lán)色的cell寬度是自適應(yīng)的,邏輯是cell的寬度根據(jù)cell的內(nèi)容來(lái)自適應(yīng),并且不能超過(guò)一定數(shù)值,否則lable添加“...”。
這個(gè)需求很快就想到了使用Autolayout的自適應(yīng)Cell,我們只要設(shè)定好cell的約束,其他的布局就交給Autolayout來(lái)做。
let flowLayout = UICollectionViewLeftAlignedLayout()
flowLayout.estimatedItemSize = CGSize(width: 125, height: 40)
self.collectionView.collectionViewLayout = flowLayout
這個(gè)頁(yè)面上面有左右切換按鈕,點(diǎn)擊之后會(huì)刷新UICollectionView的數(shù)據(jù)。進(jìn)入頁(yè)面沒(méi)有問(wèn)題,但是切換數(shù)據(jù),調(diào)用ReloaData()方法就會(huì)崩潰,崩潰信息為:
UICollectionView received layout attributes for a cell with an index path that does not exist
找了很久,沒(méi)有找到解決的辦法,但大概的原因可能是:
使用了Autolayout自適應(yīng)Cell后,UICollectionView會(huì)自動(dòng)生成相應(yīng)cell的size,并緩存起來(lái)(重點(diǎn))。當(dāng)我們獲取了新的數(shù)據(jù)并ReloaData后,UICollectionView會(huì)嘗試去拿緩存起來(lái)的cell的size(目的是提高性能)。但是此時(shí)我們的數(shù)據(jù)源發(fā)生了改變,cell的個(gè)數(shù)也變了,因此出現(xiàn)了數(shù)組下標(biāo)越界,也就崩潰了。
正確的方法是:
self.collectionView.reloadData()
self.collectionView.collectionViewLayout.invalidateLayout()
刷新數(shù)據(jù)后清空collectionViewLayout的緩存,讓Autolayout重新計(jì)算UICollectionView的cell的size。這樣就沒(méi)有問(wèn)題了。