不規則瀑布流

不規則瀑布流數組

 

一、建立一個繼承自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

相關文章
相關標籤/搜索