我是模仿上面的代碼自己寫了一份驾中,實(shí)現(xiàn)的是簡(jiǎn)單的瀑布流:
就是把UICollectionView分成三列,由數(shù)組保存每一列的高度墅茉,然后每次設(shè)置UICollectionViewLayoutAttributes的時(shí)候凿跳,獲取最短一列,計(jì)算出圖片的size僵驰,然后添加到最短一列上面喷斋。
注:這里是沒(méi)有實(shí)現(xiàn)橫向的瀑布流
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"WaterFall Flow";
// 設(shè)置 UICollectionViewLayout
WaterFallLayout *flowLayout = [[WaterFallLayout alloc] init];
flowLayout.delegate = self;
CGFloat width = ([UIScreen mainScreen].bounds.size.width - 40) / 3;
flowLayout.itemSize = CGSizeMake(width, width);
// 間隙
flowLayout.insertItemSpacing = 10;
// 內(nèi)邊距
flowLayout.sectionInsets = UIEdgeInsetsMake(10, 10, 10, 10);
// 列數(shù)
flowLayout.numberOfColumn = 3;
self.flowCV.collectionViewLayout = flowLayout;
// Register Cell
UINib *cellNib = [UINib nibWithNibName:@"FlowCollectionViewCell" bundle:[NSBundle mainBundle]];
[self.flowCV registerNib:cellNib forCellWithReuseIdentifier:@"CELL"];
[self parserJsonData];
}
#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [self.itemArray count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
FlowCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CELL" forIndexPath:indexPath];
FlowModel *model = self.itemArray[indexPath.item];
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:model.thumbURL]];
return cell;
}
WaterFallLayout.m
@interface WaterFallLayout()
// 所有Item的數(shù)量
@property (nonatomic,assign) NSUInteger numberOfItems;
// 這是一個(gè)數(shù)組唁毒,保存每一列的高度
@property (nonatomic,strong) NSMutableArray *columnHeights;
// 這是一個(gè)數(shù)組,數(shù)組中保存的是一種類型星爪,這種類型決定item的位置和大小浆西。
@property (nonatomic,strong )NSMutableArray *itemAttributes;
// 獲取最長(zhǎng)列索引
- (NSInteger)indexForLongestColumn;
// 獲取最短列索引
- (NSInteger)indexForShortestColumn;
@end
#pragma mark - UICollectionViewLayout
- (void)prepareLayout{
[super prepareLayout];
// 初始化所有高度
for (int i = 0; i < self.numberOfColumn; i++) {
self.columnHeights[i] = @(self.sectionInsets.top);
}
// 獲取item數(shù)量
self.numberOfItems = [self.collectionView numberOfItemsInSection:0];
// 循環(huán)計(jì)算每一個(gè)item的x,y,width,height
for (int i = 0; i < self.numberOfItems; i++) {
/*
這里分成三列,每計(jì)算一個(gè)Item顽腾,就取高度最短的那一列近零,放圖片上去(這里圖片寬度一致),依次疊加
*/
// 獲取最短列
NSInteger shortIndex = [self indexForShortestColumn];
// 獲取最短列高度
CGFloat shortestH = [self.columnHeights[shortIndex] floatValue];
// x
CGFloat detalX = self.sectionInsets.left + (self.itemSize.width + self.insertItemSpacing) * shortIndex;
// y
CGFloat detalY = shortestH + self.insertItemSpacing;
// h
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
CGFloat itemHeight = 0;
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(heightForItemIndexPath:)]){
itemHeight = [self.delegate heightForItemIndexPath:indexPath];
}
// 保存item frame屬性的對(duì)象
UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
attr.frame = CGRectMake(detalX, detalY, self.itemSize.width, itemHeight);
// 放入數(shù)組
[self.itemAttributes addObject:attr];
// 更新列高度
self.columnHeights[shortIndex] = @(detalY + itemHeight);
}
}
// 計(jì)算contentSize
- (CGSize)collectionViewContentSize{
// 獲取最高列
NSInteger longestIndex = [self indexForLongestColumn];
CGFloat longestH = [self.columnHeights[longestIndex] floatValue];
// 計(jì)算contentSize
CGSize contentSize = self.collectionView.frame.size;
contentSize.height = longestH + self.sectionInsets.bottom;
return contentSize;
}
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect{
return self.itemAttributes;
}
實(shí)現(xiàn)之后的效果圖:
只有縱向的瀑布流