2014-08-28 76 views
1

我正在構建一個帶有兩個部分的UICollectionView。每個部分都有自己的佈局 - 第一部分是2 * y的網格,第二部分是3 * y的網格。除了特定部分的佈局外,我還需要粘性標題(例如默認包含在UITableViews中的標題)。UICollectionView與部分特定的佈局和粘滯標頭

我已經構建了一個全功能的UICollectionViewFlowLayout子類,它可以適當地處理特定於區段的佈局和粘性標題。但是,這個解決方案在任何一個部分都不能很好地擴展到250多個單元。我做了一些分析和調查,並且問題的根源似乎是shouldInvalidateLayoutForBoundsChange。我在我的子類中返回YES,因爲用戶滾動時需要動態計算我的補充視圖(標題)。這會導致補充視圖和單元格佈局無效,這意味着流佈局一遍又一遍地調用單元格上的prepareLayout,儘管事實上單元格佈局因爲沒有更改而實際上並不需要失效。當每個刷新週期需要佈局的單元數量增加到數百或數千時,性能顯着下降。

我已經試過

我緩存UICollectionViewLayoutAttributes用於在第一計算單元,使流佈局時,系統調用layoutAttributesForItemAtIndexPath引用緩存。以這種方式進行緩存的好處是,當我經常使佈局無效時,窗口就會飛出窗口,因爲prepareLayout會每次運行它並重新填充緩存。我嘗試實現一個系統,其中prepareLayout只會在第一次傳遞時填充緩存,並在隨後的傳遞中不執行邏輯。這極大地提高了性能,並且工作,但是插入和刪除單元格時解決方案崩潰,導致斷言失敗。

我也對其他粘滯標頭的實現和涉及一致失效的類似佈局要求做了大量的研究,但這些解決方案都不需要同時解決我所具有的特定於部分的佈局問題。因此,他們推薦的解決方案是不可行的。我在這一點上有點出乎我的意料...

回答

0

對於任何有興趣實現類似的東西的人來說,這裏是我遇到的解決方案。這個解決方案避免了需要默認shouldInvalidateLayoutForBoundsChangeYES,節省了大量的CPU開銷,同時保持粘性頭完好無損。

我手動將我的標題添加爲self.collectionView的子視圖,並編寫了一個方法來跟蹤self.collectionView.contentOffset.y,以在內容滾動時適當地浮動和粘貼標題。這個解決方案的一個警告是,它不能很好地擴展到更大數量的部分;通過手動添加視圖,您會失去UICollectionReusableView的一些好處,例如出列和回收。在我的實施中,最多有5個部分,所以犧牲最小。