不規則瀑布流數組
一、建立一個繼承自UICollectionViewLayout佈局
//說明WaterFlowLayout是一個類atom
@class WaterFlowLayout;spa
二、聲明協議(實際上就是UICollectionViewDelegate中的協議,將UICollectionViewLayout*換成了自定義的WaterFlowLayout*)代理
@protocol WaterFlowLayoutDelegate<NSObject>對象
//關鍵方法,此方法的做用是返回每個Item的size的大小繼承
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;圖片
//item間 的間隙大小ci
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;it
//每行的行間距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
//擴展空間的大小
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
@end
@interface WaterFlowLayout : UICollectionViewLayout
二、瀑布流一共多少列
@property (nonatomic, assign) NSUInteger numberOfColumn;
//聲明代理
@property (nonatomic, assign) id<WaterFlowLayoutDelegate>delegate;
@end
三、在延展中分別聲明一個存放每一列的高度和存放每個item的屬性 包含 frame 以及下標的可變數組
@interface WaterFlowLayout ()
//存放每一列的高度
@property (nonatomic, retain) NSMutableArray *columnHeightsArrary;
//存放每個item的屬性 包含 frame 以及下標
@property (nonatomic, retain) NSMutableArray *attributesArray;
@end
四、實現
@implementation WaterFlowLayout
(1)//獲取最小高度的方法
- (CGFloat)minHeight {
CGFloat min = 100000;
for (NSNumber *height in _columnHeightsArrary) {
CGFloat h = [height floatValue];
if (min > h) {
min = h;
}
}
// NSLog(@"min = %f", min);
return min;
}
(2)//獲取最大值
- (CGFloat)maxHeight {
CGFloat max = 0;
for (NSNumber *height in _columnHeightsArrary) {
CGFloat h = [height floatValue];
if (max < h) {
max = h;
}
}
return max;
}
(3)//記錄最小高度的下標
- (NSUInteger)indexOfMinHeight {
NSUInteger index = 0;
for (int i = 0; i < _columnHeightsArrary.count; i ++) {
CGFloat height = [[_columnHeightsArrary objectAtIndex:i] floatValue];
if (height == [self minHeight]) {
index = i;
NSLog(@"index = %d",i);
return i;
}
}
return index;
}
(4)//重寫父類的佈局方法
- (void)prepareLayout {
[super prepareLayout];
_columnHeightsArrary = [[NSMutableArray alloc] initWithCapacity:0];
_attributesArray = [[NSMutableArray alloc] initWithCapacity:0];
//給 列高數組 裏面的對象賦初值
for (int i = 0; i < self.numberOfColumn; i ++) {
[_columnHeightsArrary addObject:@0.0];
}
CGFloat totalWidth = self.collectionView.frame.size.width;
NSLog(@"totalWidth = %f",self.collectionView.frame.size.width);
//建立 每一個人item frame中的 x、y
CGFloat x = 0;
CGFloat y = 0;
//獲取0分區下全部的item數
NSUInteger itemCount = [self.collectionView numberOfItemsInSection:0];//################
NSLog(@"itemCount = %lu",itemCount);
for (int i = 0; i < itemCount; i ++) {
//獲得集合視圖中, 列間隙的個數
NSUInteger numberOfSpace = self.numberOfColumn - 1;
//代理對象執行代理方法, 獲得 item 之間的間隙大小
CGFloat spaceWidth = [_delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:0];//##############
NSLog(@"spaceWidth = %f", spaceWidth);
//求每列的寬度,也就是每個item的width
CGFloat width = (totalWidth - spaceWidth * numberOfSpace) / self.numberOfColumn;
//**************獲取每個itemSize的大小*********************
//構建位置信息
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
//數據中原始圖片的大小
CGSize imageSize = [_delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
//經過 約分公式獲得固定寬以後的高度是多少
CGFloat height = width * imageSize.height / imageSize.width;
//求列高最小的那一列的下標
NSUInteger minHeightIndex = [self indexOfMinHeight];
//求出最小列的高度
CGFloat minHeight = [_columnHeightsArrary[minHeightIndex] floatValue];
//求出行高
CGFloat lineHeight = [_delegate collectionView:self.collectionView layout:self minimumLineSpacingForSectionAtIndex:0];
//上次總的高度 加上 行高 加上新加上的item的height, 纔是如今這一列的總高度
//minHeight爲最小列如今的高度
//lineHeight爲行間距
//height爲新加的item
_columnHeightsArrary[minHeightIndex] = [NSNumber numberWithFloat:minHeight + lineHeight + height];
//*******************************************************
UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
//記錄每個item的大小和位置
attribute.frame = CGRectMake(x, y, width, height);
//數組保存每個item的位置信息
[_attributesArray addObject:attribute];
//*******************************************************
//從新算最小列高的下標
minHeightIndex = [self indexOfMinHeight];
NSLog(@"minHeightIndex = %lu",[self indexOfMinHeight]);
//計算一次新加的item的x和y的值
x = (spaceWidth + width) * minHeightIndex;
NSLog(@"x = %f",x);
y = [self minHeight];
NSLog(@"y = %f",y);
}
}
五、內容的範圍
- (CGSize)collectionViewContentSize {
NSLog(@"maxHeight = %f",[self maxHeight]);
return CGSizeMake(self.collectionView.frame.size.width, [self maxHeight]);
}
六、加載屬性的數組使其顯示
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
return _attributesArray;
}
@end