CollectionView瀑布流添加頭視圖,自定義Cell計(jì)算高度

在開(kāi)發(fā)時(shí),看到CollectionView制作的瀑布流圖冊(cè)很好看,于是就做了一個(gè),效果確實(shí)可以。剛好在開(kāi)發(fā)時(shí)有這種布局需求,于是把之前做的瀑布流拿來(lái)改進(jìn),還是遇到了許多問(wèn)題。
先看一下效果,

![Simulator Screen Shot 2016年11月23日 下午6.08.56.png](http://upload-images.jianshu.io/upload_images/3026808-7ddd94148013a68f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

首先是,需求加了個(gè)頭視圖在頂部,在collectionView中的頭視圖跟TableView的不一樣,TableView只要設(shè)置
tableview.tableHeaderView就可以了,而collectionView需要在代理中設(shè)置頭,尾視圖。

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView *reusableView =nil;
    if (kind ==UICollectionElementKindSectionHeader) {
        UICollectionReusableView *header = [collectionViewdequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithReuseIdentifier:@"HeaderView"forIndexPath:indexPath];
        reusableView = header;
    }
    reusableView.backgroundColor = [UIColorgreenColor];
    if (kind ==UICollectionElementKindSectionFooter)
    {
        UICollectionReusableView *footerview = [collectionViewdequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooterwithReuseIdentifier:@"FooterView"forIndexPath:indexPath];
        footerview.backgroundColor = [UIColorpurpleColor];
        reusableView = footerview;
    }
    return reusableView;
}

但是你會(huì)發(fā)現(xiàn),使用瀑布流的時(shí)候,UICollectionViewFlowLayout是自定義的布局,collectionView的代理不會(huì)走,在網(wǎng)上搜了很多也沒(méi)有什么解決方法,都是一個(gè)版本的復(fù)制粘貼使用這種代理方法來(lái)設(shè)置的,因?yàn)樗麄儧](méi)用使用自定義的瀑布流布局,Cell都是相同大小的布局,所以,這里就比較坑了。
最后在CocoChina的一個(gè)論壇搜到一個(gè)說(shuō)加HeaderView的,看了一下,就是在自定義的Layout中添加加一個(gè) Header類型的 UICollectionViewLayoutAttributes就可以。然后我把瀑布流的Cell的起始位置從headerView的最大Y開(kāi)始布局。這樣設(shè)置之后,controllerView中的代理方法才會(huì)走,要記得注冊(cè)頭視圖哦,不然會(huì)崩。
然后還有一個(gè)問(wèn)題就是,瀑布流自定義布局,這個(gè)網(wǎng)上很多,不懂的自己搜,我也是照網(wǎng)上的做,一開(kāi)始內(nèi)容都是圖片,只要在自定義的Layout中根據(jù)當(dāng)前cell的圖片設(shè)置該cell的布局大小就行。方法也是先走的layout中的設(shè)置方法,再走CollectionView的代理方法,所以這里就比較坑了,要先把每個(gè)cell的大小根據(jù)內(nèi)容計(jì)算出來(lái)給layout布局設(shè)置,再去代理方法中設(shè)置自定義的Cell的內(nèi)容。一開(kāi)始內(nèi)容是一張圖片還好,只要每次取出來(lái)計(jì)算image.size就可以了,而需求是自定義的cell中有圖片,文字的一些內(nèi)容,所以只能專門寫一個(gè)計(jì)算cell寬高的類。網(wǎng)上有人寫了個(gè)緩存這個(gè)寬高值的類,我就沒(méi)有去做了。我貼一下關(guān)鍵的代碼吧。
自定義的瀑布流布局Layout中,添加頭和cell的Attribute,

- (void)prepareLayout
{
    [superprepareLayout];
    
    CGFloat screenW =CGRectGetWidth([UIScreenmainScreen].bounds);
    
   // 重置每一列的最大Y值
    [self.columnMaxYArrayremoveAllObjects];
    for (int i =0; i < self.columnCount; i ++) {
        [self.columnMaxYArrayaddObject:@(self.sectionEdge.top)];
    }
    //計(jì)算所有cell的布局屬性
    [self.attributeArrayremoveAllObjects];
    
    //頭部視圖
    UICollectionViewLayoutAttributes * layoutHeader = [UICollectionViewLayoutAttributeslayoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithIndexPath:[NSIndexPathindexPathWithIndex:0]];
    layoutHeader.frame =CGRectMake(0,0, screenW, self.sectionEdge.top);
    [self.attributeArrayaddObject:layoutHeader];
    
    //item內(nèi)容視圖
    NSInteger count = [self.collectionViewnumberOfItemsInSection:0];
    for (int i =0; i < count; i ++) {
        UICollectionViewLayoutAttributes * attribute = [selflayoutAttributesForItemAtIndexPath:[NSIndexPathindexPathForRow:i inSection:0]];
        [self.attributeArrayaddObject:attribute];
    }
    
}

controllerView中要注冊(cè)Cell和頭,這里的cell和頭都是自定義的,
[_communityCollectionViewregisterClass:[CommunityCollectionViewCellclass]forCellWithReuseIdentifier:@"CollectionCell"];
    [_communityCollectionViewregisterClass:[CommunityHeaderViewclass] forSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithReuseIdentifier:@"HeaderView"];

在拿到請(qǐng)求數(shù)據(jù)的地方調(diào)用該方法為自定義的瀑布流Layout設(shè)置高度回調(diào),里面的方法是根據(jù)數(shù)據(jù)內(nèi)容來(lái)計(jì)算布局高度的,這個(gè)根據(jù)自己的內(nèi)容來(lái)計(jì)算。

#pragma mark - 計(jì)算Item高度回調(diào)
- (void)counterItemHightByCommunityDataArray:(NSArray *)dataArray
{
    _communityLayout.itemHightBlock = ^CGFloat (NSIndexPath * index,CGFloat width){
        
        CGFloat itemH = [cellHCountercountCellHightByCommunityData:communityDataArray[index.item]];

        return itemH;
    };
}

然后collectionView的Heard頭視圖設(shè)置代理就可以走了,設(shè)置一下自定義的頭視圖,

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView * reusableview =nil;
    
    if (kind ==UICollectionElementKindSectionHeader){
        
        _heardView = [collectionViewdequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithReuseIdentifier:@"HeaderView"forIndexPath:indexPath];
        reusableview = _heardView;
    }
    return reusableview;
}

好了,關(guān)鍵的代碼就這些了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 翻譯自“Collection View Programming Guide for iOS” 0 關(guān)于iOS集合視...
    lakerszhy閱讀 4,076評(píng)論 1 22
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,408評(píng)論 4 61
  • 實(shí)現(xiàn)瀑布流簡(jiǎn)單,實(shí)現(xiàn)分區(qū)瀑布流,并且每個(gè)區(qū)的瀑布流的列數(shù)不一樣且有區(qū)頭和區(qū)尾,就不是太容易了。我嫌麻煩不愿意自己寫...
    ac986bb0e59a閱讀 833評(píng)論 2 3
  • 從來(lái)沒(méi)有這么一個(gè)名字, 能夠在我夢(mèng)里這么多次, 每叫一個(gè)人都是這個(gè)名字! 曾幾何時(shí), 你瞧瞧的來(lái)到我的心里, 曾經(jīng)...
    朱朔方閱讀 345評(píng)論 0 1
  • 2017—10—13 星期五 天氣:晴 媽媽給我預(yù)約了下午去金寶貝早教中心3點(diǎn)15分的運(yùn)動(dòng)課,這幾...
    元朗媽媽閱讀 1,042評(píng)論 0 1

友情鏈接更多精彩內(nèi)容