CollectionView瀑布流添加头视图,自定义Cell计

作者: 来自南方的熊 | 来源:发表于2016-12-30 18:18 被阅读0次

    在开发时,看到CollectionView制作的瀑布流图册很好看,于是就做了一个,效果确实可以。刚好在开发时有这种布局需求,于是把之前做的瀑布流拿来改进,还是遇到了许多问题。
    先看一下效果,

    ![Simulator Screen Shot 2016年11月23日 下午6.08.56.png](https://img.haomeiwen.com/i3026808/7ddd94148013a68f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    首先是,需求加了个头视图在顶部,在collectionView中的头视图跟TableView的不一样,TableView只要设置
    tableview.tableHeaderView就可以了,而collectionView需要在代理中设置头,尾视图。

    - (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;
    }
    

    但是你会发现,使用瀑布流的时候,UICollectionViewFlowLayout是自定义的布局,collectionView的代理不会走,在网上搜了很多也没有什么解决方法,都是一个版本的复制粘贴使用这种代理方法来设置的,因为他们没用使用自定义的瀑布流布局,Cell都是相同大小的布局,所以,这里就比较坑了。
    最后在CocoChina的一个论坛搜到一个说加HeaderView的,看了一下,就是在自定义的Layout中添加加一个 Header类型的 UICollectionViewLayoutAttributes就可以。然后我把瀑布流的Cell的起始位置从headerView的最大Y开始布局。这样设置之后,controllerView中的代理方法才会走,要记得注册头视图哦,不然会崩。
    然后还有一个问题就是,瀑布流自定义布局,这个网上很多,不懂的自己搜,我也是照网上的做,一开始内容都是图片,只要在自定义的Layout中根据当前cell的图片设置该cell的布局大小就行。方法也是先走的layout中的设置方法,再走CollectionView的代理方法,所以这里就比较坑了,要先把每个cell的大小根据内容计算出来给layout布局设置,再去代理方法中设置自定义的Cell的内容。一开始内容是一张图片还好,只要每次取出来计算image.size就可以了,而需求是自定义的cell中有图片,文字的一些内容,所以只能专门写一个计算cell宽高的类。网上有人写了个缓存这个宽高值的类,我就没有去做了。我贴一下关键的代码吧。
    自定义的瀑布流布局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)];
        }
        //计算所有cell的布局属性
        [self.attributeArrayremoveAllObjects];
        
        //头部视图
        UICollectionViewLayoutAttributes * layoutHeader = [UICollectionViewLayoutAttributeslayoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithIndexPath:[NSIndexPathindexPathWithIndex:0]];
        layoutHeader.frame =CGRectMake(0,0, screenW, self.sectionEdge.top);
        [self.attributeArrayaddObject:layoutHeader];
        
        //item内容视图
        NSInteger count = [self.collectionViewnumberOfItemsInSection:0];
        for (int i =0; i < count; i ++) {
            UICollectionViewLayoutAttributes * attribute = [selflayoutAttributesForItemAtIndexPath:[NSIndexPathindexPathForRow:i inSection:0]];
            [self.attributeArrayaddObject:attribute];
        }
        
    }
    
    controllerView中要注册Cell和头,这里的cell和头都是自定义的,
    [_communityCollectionViewregisterClass:[CommunityCollectionViewCellclass]forCellWithReuseIdentifier:@"CollectionCell"];
        [_communityCollectionViewregisterClass:[CommunityHeaderViewclass] forSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithReuseIdentifier:@"HeaderView"];
    
    

    在拿到请求数据的地方调用该方法为自定义的瀑布流Layout设置高度回调,里面的方法是根据数据内容来计算布局高度的,这个根据自己的内容来计算。

    #pragma mark - 计算Item高度回调
    - (void)counterItemHightByCommunityDataArray:(NSArray *)dataArray
    {
        _communityLayout.itemHightBlock = ^CGFloat (NSIndexPath * index,CGFloat width){
            
            CGFloat itemH = [cellHCountercountCellHightByCommunityData:communityDataArray[index.item]];
    
            return itemH;
        };
    }
    

    然后collectionView的Heard头视图设置代理就可以走了,设置一下自定义的头视图,

    - (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;
    }
    

    好了,关键的代码就这些了。

    相关文章

      网友评论

        本文标题: CollectionView瀑布流添加头视图,自定义Cell计

        本文链接:https://www.haomeiwen.com/subject/oinmvttx.html