ios UICollectionView reloadData沒法更新的奇怪問題。

報錯    Assertion failure in -[UICollectionViewData invalidateItemsAtIndexPaths:]佈局

 

近來偶爾用到UICollectionView,對於九宮格之類的佈局仍是很方便的。但使用過程當中卻出現一個奇怪的問題,暫時沒時間仔細研究。先記錄。測試

在UICollectionViewCell中定義一個圖標和一個文本,顯示的效果是典型的九宮格。默認會有幾條數據,點擊最後一個cell會彈出編輯框添加自定義的cell。使用過程當中出現的問題時,在第二行最後一個添加的自定義cell,圖標怎麼都改變不了。若是將整個view切換一下,顯示又變成正常了。以下圖:ui

查看打印出來的數據,是正常的。以下:spa

 

(
{
    index = 0;
    name = "\U5915\U9633";
    thumb = "sunset_btn_nor";
},
{
    index = 1;
    name = "\U665a\U9910";
    thumb = "dinner_btn_nor";
},
{
    index = 2;
    name = "\U770b\U7535\U89c6";
    thumb = "tv_btn_nor";
},
{
    index = 3;
    name = "\U6e29\U548c";
    thumb = "soft_btn_nor";
},
{
    index = 4;
    name = "\U51b7\U5149";
    thumb = "coldlight_btn_nor";
},
{
    index = 5;
    name = night;
    thumb = "my_btn_nor";
},
{
    index = 6;
    name = morning;
    thumb = "my_btn_nor";
},
{
    index = 7;
    name = sunset;
    thumb = "my_btn_nor";
},
{
    index = 8;
    name = "\U81ea\U5b9a\U4e49";
    thumb = "add_btn_nor";
}
)

 

添加斷點,發現數據也沒有問題。代碼的處理方式是在插入或者更新數據後,調用code

 

 

 

[collectionView reloadData];blog

的方法。it

網上搜索,也看到有人問相似的問題。有些人給出的解決辦法是加一個空的UIView在上面,強制整個collection view刷新。但感受不是好的辦法。io

後來試了更新指定項,問題就不出現了。table

如下兩種方法均有效:class

 

[self.collectionViewreloadItemsAtIndexPaths:@[[NSIndexPathindexPathForRow:7inSection:0]]];

或者

 

[self.collectionViewreloadSections:[NSIndexSetindexSetWithIndex:0]];

 

至於爲何reloadData會無效。這個暫時留下,等有空的時候再研究一下其原理。或者有牛人知道也請不吝賜教。

 

另外,這狀況也提醒咱們,能肯定加載某個子項的,仍是調用直接刷新指定項更好。一來效率高,二來避免出現莫名其妙的現象。

 

==================


昨天的問題補充一下。發現不是reloadData的問題。後來在測試中,使用reloadSections也會出現問題。
跟蹤了一下,發如今reloadData過程當中,最後一個(也就是新增長)的一個cell沒有調用layoutSubviews。由於是在layoutSubviews中改變custom cell的image和label的值,因此新增長的cell沒有刷新。後來換成了在賦值過程當中調用更新image和label的代碼,這樣不管reloadData和reloadSections都有效了,由於這樣保證了加載數據的時候imageView和label都被調用。或者也能夠在cellForRowAtIndexPath中調用[cell setNeedsLayout];去強制調用layoutSubviews,這樣也達到更新的效果。
可是有點比較奇怪的是,以前的uitableview和uicollectionview自定義cell都是在layoutSubviews裏面更新對應的控件,卻沒出現過問題。是否是iOS7之後,加載的機制發生變化了。這個有待進一步研究。
今天查找資料的時候,順便收集了一個圖表,圖表清楚說明了會引發調用layoutSubviews的操做。(x表示被調用)

相關文章
相關標籤/搜索