UICollectionView的簡單使用(二)— 瀑布流(石工佈局)

  有了上一篇的基礎,發現如今經常使用UICollectionView的佈局是瀑布流(石工佈局),首先我看看默認大小不一的佈局。git

1.默認佈局github

  咱們在ViewController.m文件添加一下代碼app

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat randomHeight = 100 + (arc4random() % 140);
    return CGSizeMake(100, randomHeight);//100-240之間
}

  模擬器運行以下:dom

  這就是默認的狀況,但不是咱們想要的狀況。佈局

2.瀑布流(石工佈局)ui

  接下來就要建立一個UICollectionViewLayout的子類,佈局子類覆蓋父類的方法atom

  

2.1 在YFCollectionViewLayout.h文件中添加spa

#import <UIKit/UIKit.h>

@class YFCollectionViewLayout;

@protocol YFCollectionViewLayoutDelegate <NSObject>
@required
- (CGFloat)collectionView:(UICollectionView *) collectionView
                   layout:(YFCollectionViewLayout *)layout
 heightForItemAtIndexPath:(NSIndexPath *) indexPath;

@end

@interface YFCollectionViewLayout : UICollectionViewLayout
/**
 *  列數
 */
@property (nonatomic, assign) NSUInteger numberOfColumns;
/**
 *  間距
 */
@property (nonatomic, assign) CGFloat interItemSpacing;
@property (nonatomic, weak)  id<YFCollectionViewLayoutDelegate> delegate;

@end

2.2  在YFCollectionViewLayout.m文件中代理

子類須要覆蓋的方法有code

/**
 *  佈局準備方法,能夠把一些計算的東西放到這裏
 */
- (void)prepareLayout;
/**
 *  每一個子控件的一些屬性
 */
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;
/**
 *  集合視圖總體大小
 *
 */
- (CGSize)collectionViewContentSize;
//
//  YFCollectionViewLayout.m
//  WaterfallFlowCollection
//
//  Created by apple on 15/12/15.
//  Copyright © 2015年 藍天的夢想. All rights reserved.
//

#import "YFCollectionViewLayout.h"

@interface YFCollectionViewLayout ()
/**
 *  最後列的Y值
 */
@property (nonatomic, strong) NSMutableDictionary *lastYValueForColumn;
/**
 * 佈局信息
 */
@property (nonatomic, strong) NSMutableDictionary *layoutInfo;
@end

@implementation YFCollectionViewLayout

/**
 *  佈局準備方法,能夠把一些計算的東西放到這裏
 */
-(void) prepareLayout {
    
     [super prepareLayout];
    
    self.lastYValueForColumn = [NSMutableDictionary dictionary];
    CGFloat currentColumn = 0;
    CGFloat fullWidth = self.collectionView.frame.size.width;
    CGFloat availableSpaceExcludingPadding = fullWidth - (self.interItemSpacing * (self.numberOfColumns + 1));
    CGFloat itemWidth = availableSpaceExcludingPadding / self.numberOfColumns;
    self.layoutInfo = [NSMutableDictionary dictionary];
    NSIndexPath *indexPath;
    NSInteger numSections = [self.collectionView numberOfSections];
    
    for(NSInteger section = 0; section < numSections; section++)  {
        
        NSInteger numItems = [self.collectionView numberOfItemsInSection:section];
        for(NSInteger item = 0; item < numItems; item++){
            indexPath = [NSIndexPath indexPathForItem:item inSection:section];
            
            UICollectionViewLayoutAttributes *itemAttributes =
            [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
            
            CGFloat x = self.interItemSpacing + (self.interItemSpacing + itemWidth) * currentColumn;
            CGFloat y = [self.lastYValueForColumn[@(currentColumn)] doubleValue];
            CGFloat height = [((id<YFCollectionViewLayoutDelegate>)self.collectionView.delegate)
                              collectionView:self.collectionView
                              layout:self
                              heightForItemAtIndexPath:indexPath];
            
            itemAttributes.frame = CGRectMake(x, y, itemWidth, height);
            y+= height;
            y += self.interItemSpacing;
            
            self.lastYValueForColumn[@(currentColumn)] = @(y);
            
            currentColumn ++;
            if(currentColumn == self.numberOfColumns) currentColumn = 0;
            self.layoutInfo[indexPath] = itemAttributes;
        }
    }
}

/**
 *  每一個子控件的一些屬性
 */
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
   NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.layoutInfo.count];
    
    [self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
                                                         UICollectionViewLayoutAttributes *attributes,
                                                         BOOL *stop) {
        
        if (CGRectIntersectsRect(rect, attributes.frame)) {
            [allAttributes addObject:attributes];
        }
    }];
    return allAttributes;
}

/**
 *  集合視圖總體大小
 *
 */
-(CGSize) collectionViewContentSize {
    
    NSUInteger currentColumn = 0;
    CGFloat maxHeight = 0;
    do {
        CGFloat height = [self.lastYValueForColumn[@(currentColumn)] doubleValue];
        if(height > maxHeight)
            maxHeight = height;
        currentColumn ++;
    } while (currentColumn < self.numberOfColumns);
    
    return CGSizeMake(self.collectionView.frame.size.width, maxHeight);
}

@end

打開Storyboard的文件,給CollectionViewLayout設置類名

打開ViewCollection.m文件,拖線並設置代理

設置間距和列數

設置代理方法

模擬器運行結果以下

 

下載地址:https://github.com/yifazhang/WaterfallFlowCollection

相關文章
相關標籤/搜索