iOS开发之瀑布流

来源:互联网 发布:linux定时器函数 编辑:程序博客网 时间:2024/05/01 03:28

所谓瀑布流即是自定义CollectionView的layout,继承UICollectionViewFlowLayout

创建一个类CustomLayout

#import <UIKit/UIKit.h>

//定义一个代理给返回给外界每个item的size

@class CustomLayout;

@protocol CustomLayoutDelegate <NSObject>


-(CGSize)collectionView :(UICollectionView * )collectionView layout:(CustomLayout *)layout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;

@end


@interface CustomLayout : UICollectionViewFlowLayout


@property(nonatomic,assign)id<CustomLayoutDelegate>delegate;

//自定义初始化方法,参数由外界定义一共有几列

-(instancetype)initWithNumberOfColumns:(NSUInteger)columns;




@end

**************************

#import "CustomLayout.h"


@interface CustomLayout  ()

@property (nonatomic ,retain)NSMutableArray * frameArr;//存放每一列的frame

@property (nonatomic ,retain)NSMutableArray * attributesArr;//存放每一个item的属性

@end


@implementation CustomLayout


{

    NSUInteger _numofCloumns;//一共有多少列

}


-(void)dealloc

{

    [_frameArrrelease];

    [_attributesArrrelease];

    [superdealloc];

}



-(NSMutableArray *)attributesArr

{

    if (_attributesArr ==nil ) {

        self.attributesArr = [NSMutableArrayarrayWithCapacity:0];

    }

    return_attributesArr;

}


-(instancetype)initWithNumberOfColumns:(NSUInteger)columns

{

    self = [superinit];

    if (self) {

        _numofCloumns = columns;

    }

    returnself;

}


-(NSMutableArray *)frameArr

{

    if (_frameArr ==nil ) {

        self.frameArr = [NSMutableArrayarrayWithCapacity:0];

    }

    return_frameArr;

}

//准备每个item存放的位置

-(void)prepareLayout

{

    [superprepareLayout];

    [self.attributesArrremoveAllObjects];

//    计算在当前列数下每个item的宽度;

    CGFloat  itemWith =self.collectionView.bounds.size.width/_numofCloumns;

//    通过for循环,在数组中每一列总得frame。由于开始时不知道frame的高度,height设置为0

    for (int i =0 ; i < _numofCloumns; i ++) {

        CGRect frame =CGRectMake(itemWith * i, 0, itemWith,0);

        NSValue * frameValue = [NSValuevalueWithCGRect:frame];

        [self.frameArraddObject:frameValue];

    }

//    确定每个item存放的位置

    for (int i =0 ; i < [self.collectionViewnumberOfItemsInSection:0]; i++) {

             NSIndexPath * indexPath = [NSIndexPathindexPathForItem:i inSection:0];

        CGSize itemSize = [_delegatecollectionView:self.collectionViewlayout:selfsizeForItemAtIndexPath:indexPath];

        CGFloat height = itemSize.height * itemWith / itemSize.width;

//        获取所有列里面的最小frame

        NSUInteger  index =0;

        CGRect frame = [selfminimumFrameOfIndex:&index];

        CGFloat x = frame.origin.x;

        CGFloat y = frame.size.height;

        CGRect itemFrame =CGRectMake(x, y, itemWith, height);

//        将item的相关信息例如itemFrame,indexPath封装成一个  UICollectionViewLayoutAttributes对象中

        UICollectionViewLayoutAttributes * attributes = [UICollectionViewLayoutAttributeslayoutAttributesForCellWithIndexPath:indexPath];

        attributes.frame = itemFrame;

        [self.attributesArraddObject:attributes];

//        更新数组(由于新添加了item,所以需要修改数组对应元素)

        CGRect newFrame =CGRectMake(frame.origin.x,0, itemWith, frame.size.height + height);

        [self.frameArrreplaceObjectAtIndex:index withObject:[NSValuevalueWithCGRect:newFrame] ];

        

    }

    

    

}


//返回所有列里面最小的frame。用于计算下一个item存放的位置的x ,y

-(CGRect)minimumFrameOfIndex:(NSUInteger *)index

{

    CGRect minFrame =CGRectMake(0,0, 0,NSIntegerMax);

    for (int i =0 ;  i < self.frameArr.count; i++) {

        NSValue * frameValue =self.frameArr[i];

        if (CGRectGetHeight(minFrame)>CGRectGetHeight([frameValue CGRectValue]) ){

            minFrame =[frameValue CGRectValue];

            *index = i ;

        }

    }

    return minFrame;

}



//返回数组里面最高的高度

-(CGFloat)maximumHeight

{

    CGFloat height =NSIntegerMin;

    for (int i =0 ; i < self.frameArr.count; i ++) {

        NSValue * frameValue =self.frameArr[i];

        CGRect frame = [frameValueCGRectValue];

        if (CGRectGetHeight(frame)> height) {

            height = CGRectGetHeight(frame);

        }

    }

    return height;

}



//返回collectionView可滑动的区域

-(CGSize)collectionViewContentSize

{

    returnCGSizeMake(self.collectionView.bounds.size.width, [self maximumHeight]);

}

//返回所有itemlayout属性

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

{

    returnself.attributesArr;

}

@end


0 0
原创粉丝点击