ZJCollectionLayout 布局

不同宽度Item布局

 

#import

 

NS_ASSUME_NONNULL_BEGIN

@class ZJCollectionLayout;

 

@protocol ZJCollectionLayoutDelegate

/** */

- (CGSize)flowLayout:(ZJCollectionLayout *) layout itemSizeForItemAtIndexPath:(NSIndexPath*)indexPath;

/** 每一列item之间的间距*/

- (CGFloat)itemColumnMarginInFlowLayout:(ZJCollectionLayout *) layout;

/** 每一行item之间的间距*/

- (CGFloat)itemRowMarginInFlowLayout:(ZJCollectionLayout *) layout;

/** 设置于collectionView边缘的间距*/

- (UIEdgeInsets)itemSectionInsetMarginInFlowLayout:(ZJCollectionLayout *) layout;

@end

 

@interface ZJCollectionLayout : UICollectionViewLayout

@property (nonatomic,weak) id delegate;

@end

 

NS_ASSUME_NONNULL_END

 

#import "ZJCollectionLayout.h"

@interface ZJCollectionLayout()

@property (strong,nonatomic)NSMutableArray * attrsArray;  /** 存放每一个item的布局属性 */

@property (strong,nonatomic)NSMutableArray * sectionArray;/** count>0 表示换行 y 值计算方法改变*/

@property (assign,nonatomic)CGFloat columnMargin;

@property (assign,nonatomic)CGFloat rowMargin;

@property (assign,nonatomic)UIEdgeInsets sectionInset;

@property (strong,nonatomic)UICollectionViewLayoutAttributes *lastObject;

@end

@implementation ZJCollectionLayout

/** 懒加载 */

-(NSMutableArray *)attrsArray{

    if (!_attrsArray){

        _attrsArray = [NSMutableArray array];

    }

    return _attrsArray;

}

 

/** 懒加载 */

-(NSMutableArray *)sectionArray{

    if (!_sectionArray){

        _sectionArray = [NSMutableArray array];

    }

    return _sectionArray;

}

- (void)prepareLayout{

    

    [super prepareLayout];

    [self.attrsArray removeAllObjects];

    [self setRowMargin:10];

    [self setColumnMargin:10];

    [self setSectionInset:UIEdgeInsetsMake(10, 10, 10, 10)];

    NSInteger cou = [self.collectionView numberOfItemsInSection:0];

    for (NSInteger i = 0 ; i< cou; i ++) {

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

        UICollectionViewLayoutAttributes *attr = [self layoutAttributesForItemAtIndexPath:indexPath];

        [self.attrsArray addObject:attr];

    }

}

- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{

    return self.attrsArray;

}

//返回指定indexPath的item的布局信息。子类必须重载该方法,该方法只能为cell提供布局信息,不能为补充视图和装饰视图提供。

-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{

    CGFloat width = self.collectionView.frame.size.width;

    

    CGSize frameSize = [self.delegate flowLayout:self itemSizeForItemAtIndexPath:indexPath];

    //计算每一个item的位置

    CGFloat lastObjectX = CGRectGetMaxX(self.lastObject.frame);

    CGFloat x = lastObjectX+self.columnMargin;

    CGFloat y = self.sectionInset.top;

    if (x+frameSize.width+self.sectionInset.right>width) { // 换行

        [self.sectionArray addObject:indexPath];

        x = self.rowMargin;

        CGFloat lastObjectY = CGRectGetMaxY(self.lastObject.frame);

        y = lastObjectY+self.rowMargin;

    }else if(self.sectionArray.count>0) {

        y = self.lastObject.frame.origin.y;

    }

    //创建布局属性

    UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    //设置item的frame

    attrs.frame = CGRectMake(x, y, frameSize.width, frameSize.height);

    [self setLastObject:attrs];

    return attrs;

}

//返回collectionView内容区的宽度和高度,子类必须重载该方法,返回值代表了所有内容的宽度和高度,而不仅仅是可见范围的,collectionView通过该信息配置它的滚动范围,默认返回 CGSizeZero。

-(CGSize)collectionViewContentSize{

    return CGSizeMake(0, CGRectGetMaxY(self.lastObject.frame)+self.sectionInset.bottom);

}

 

//该方法用来决定是否需要更新布局。如果collection view需要重新布局返回YES,否则返回NO,默认返回值为NO。子类重载该方法的时候,基于是否collection view的bounds的改变会引发cell和view布局的改变,给出正确的返回值。

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{

    return NO;

}

#pragma mark -

- (CGFloat)columnMargin{

    if([self.delegate respondsToSelector:@selector(itemColumnMarginInFlowLayout:)]){

        return  [self.delegate itemColumnMarginInFlowLayout:self];

    }

    return 10;

}

- (CGFloat)rowMargin{

    if([self.delegate respondsToSelector:@selector(itemRowMarginInFlowLayout:)]){

        return [self.delegate itemRowMarginInFlowLayout:self];

    }

    return 10;

}

- (UIEdgeInsets)sectionInset{

    if([self.delegate  respondsToSelector:@selector(itemSectionInsetMarginInFlowLayout:)]){

        return [self.delegate itemSectionInsetMarginInFlowLayout:self];

    }

    return UIEdgeInsetsMake(10, 10, 10, 40);

}

@end

你可能感兴趣的:(Objectvie_C)