有了上一篇的基礎,發現如今經常使用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文件,拖線並設置代理
設置間距和列數
設置代理方法
模擬器運行結果以下