iOS開發(fā)-瀑布流

前言:

忙里偷閑,忽然想起以前自己實(shí)現(xiàn)的一個(gè)瀑布流功能,就拿出來完善了下;說起這個(gè)瀑布流,還是在以前自己還是iOS開發(fā)小白的時(shí)候,學(xué)習(xí)來的,后來我自己動(dòng)手模仿蘋果API里自帶的布局類寫法,重新實(shí)現(xiàn)了下,方便大家可以更熟悉的使用,話不多說,進(jìn)入正題。

一、準(zhǔn)備

1、首先準(zhǔn)備好plist文件,以及需要用到的工具類,工具類可以自己下載導(dǎo)入,也可以cocoapods導(dǎo)入


1533266010749.jpg

1533266033205.jpg

1533266147661.jpg

1533266173431.jpg

2、接著創(chuàng)建我們的布局類WaterFallFlowLayout,繼承于UICollectionViewLayout,既然是模仿,那我們就要設(shè)定好對(duì)應(yīng)的屬性和代理方法,如下圖:


1533266493595.jpg

以及我們的數(shù)組和初始化


1533266583321.jpg

二、實(shí)現(xiàn)

實(shí)現(xiàn)自定義布局,我們需要實(shí)現(xiàn)布局類里的四個(gè)方法,如下:
1、- (void)prepareLayout {......}
具體實(shí)現(xiàn)代碼如下

//初始化加載,每次刷新也都會(huì)加載
- (void)prepareLayout {
    [super prepareLayout];
    //刷新時(shí)清空item屬性數(shù)組
    [self.attributes removeAllObjects];
    //刷新時(shí)清空列高數(shù)組
    [self.itemHeights removeAllObjects];
    //添加每列的默認(rèn)起始高度
    for (int i = 0; i < kScreenWidth/self.itemWidth; i++) {
        [self.itemHeights addObject:@(self.minimumLineSpacing + self.headerReferenceSize.height + self.sectionInset.top)];
    }
    //獲取collectionView的所有區(qū)數(shù)量
    NSUInteger sectionCount = [self.collectionView numberOfSections];
    //獲取collectionView的所有單元格數(shù)量
    for (int i = 0; i < sectionCount; i++) {
        //獲取每個(gè)區(qū)的單元格數(shù)量
        NSUInteger itemCount = [self.collectionView numberOfItemsInSection:i];
        for (int j = 0; j < itemCount; j++) {
            //得到每個(gè)單元格布局屬性
            UICollectionViewLayoutAttributes *attribute = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:j inSection:i]];
            //添加進(jìn)布局屬性數(shù)組中
            [self.attributes addObject:attribute];
        }
    }
    
}

2、- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {......}
具體實(shí)現(xiàn)代碼如下:

//返回每個(gè)單元格的布局屬性
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
    //創(chuàng)建每個(gè)單元格的布局屬性
    UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    //計(jì)算高h(yuǎn)eight
    CGFloat height = 0;
    if (self.delegate) {
        height = [self.delegate waterFallFlowLayout:self heightForItemAtIndexPath:indexPath width:self.itemWidth];
    }
    //計(jì)算坐標(biāo)x和y,需要找到最小的列高值和列號(hào),所以需要一個(gè)數(shù)組來存放所有的列高
    //聲明一個(gè)列號(hào)代表我們需要尋找的最小的列高值,默認(rèn)為0
    NSUInteger minColumn = 0;
    //聲明一個(gè)最小的列高值,獲取第0列的列高值,默認(rèn)為最小的
    CGFloat minItemHeight = [self.itemHeights[0] floatValue];
    //for循環(huán)尋找最小的列高值和列號(hào)
    for (int i = 1; i < kScreenWidth/self.itemWidth; i++) {
        CGFloat itemHeight = [self.itemHeights[i] floatValue];
        if (itemHeight < minItemHeight) {
            minItemHeight = itemHeight;
            minColumn = i;
        }
    }
    //for循環(huán)結(jié)束,最小的列號(hào)和列高值就確定了,此時(shí)先計(jì)算坐標(biāo)x
    CGFloat x = self.sectionInset.left + minColumn * self.minimumInteritemSpacing + minColumn * self.itemWidth;
    //此時(shí)坐標(biāo)y也就確定了
    CGFloat y;
    //獲得列數(shù)
    NSUInteger columnCount = kScreenWidth/self.itemWidth;
    if (indexPath.item/columnCount == 0) {
        if (indexPath.section == 0) {
            y = self.headerReferenceSize.height + minItemHeight;
        } else {
            y = minItemHeight;
        }
    } else {
        y = self.minimumLineSpacing + minItemHeight;
    }
    //設(shè)置每個(gè)單元格的大小
    attribute.frame = CGRectMake(x, y, self.itemWidth, height);
    //更新列高數(shù)組中的的高度
    self.itemHeights[minColumn] = @(CGRectGetMaxY(attribute.frame));
    return attribute;
}

3、第三個(gè)方法比較簡單,直接貼代碼

//返回布局屬性數(shù)組
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
    return self.attributes;
}

4、- (CGSize)collectionViewContentSize {......}
具體實(shí)現(xiàn)代碼如下:

//返回集合視圖內(nèi)容大小
- (CGSize)collectionViewContentSize {
    CGFloat maxItemHeight = [self.itemHeights[0] floatValue];
    for (int i = 1; i < kScreenWidth/self.itemWidth; i++) {
        CGFloat height = [self.itemHeights[i] floatValue];
        if (maxItemHeight < height) {
            maxItemHeight = height;
        }
    }
    CGFloat collectionViewHeight = maxItemHeight + self.headerReferenceSize.height + self.footerReferenceSize.height + self.sectionInset.bottom;
    return CGSizeMake(kScreenWidth, collectionViewHeight);
}

三、運(yùn)行

主界面添加上集合視圖,實(shí)現(xiàn)功能,具體使用很簡單,就不多說,直接上運(yùn)行結(jié)果,如下圖:


1533267511446.jpg

大功告成!

四、最后

附上demo:WaterFallFlowLayout

最后編輯于
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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