iOS 简单的横向多区自适应 UICollectionViewLayout

因为项目需求,需要实现多区标签选择,标签的长度还是不固定的,网上没有找到合适的,所以自己研究了下自定义Layout,实现了多行分区不定宽高的CustomLayout,一下是代码:
.h文件代码

#import 

NS_ASSUME_NONNULL_BEGIN
@protocol SSLCollectionViewLayoutDelegate 
@optional;
//如果注册区头,则必须实现改代理方法
-(CGFloat)heightOfSectionHeaderForIndexPath:(NSIndexPath *)indexPath;
//如果注册区头,则必须实现改代理方法
-(CGFloat)heightOfSectionFooterForIndexPath:(NSIndexPath *)indexPath;
//单元格返回宽度
- (CGFloat)collectionView:(UICollectionView *)collectionView wideForItemAtIndexPath:(NSIndexPath *)indexPath;
@end
@interface SSLCollectionViewLayout : UICollectionViewLayout
//item 的高度
@property (nonatomic,assign) CGFloat  itemHeight ;
//item左右的间距
@property (nonatomic,assign) CGFloat  itemLRSpace;
//区边距
@property (nonatomic, assign) UIEdgeInsets sectionEdge;
@property (nonatomic, assign) CGFloat collectionViewWidth;
//item上下的间距
@property (nonatomic,assign) CGFloat  itemHVSpace;
@property (nonatomic, assign) iddelegate;
@end


NS_ASSUME_NONNULL_END

.m文件代码

#import "SSLCollectionViewLayout.h"
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define kBaseLine(a) (CGFloat)a * SCREEN_WIDTH / 375.0
@interface SSLCollectionViewLayout ()
@property (nonatomic, assign) CGFloat totalHeight; ///总高度
@property (nonatomic, assign) CGFloat itemX;//单元格的x
@property (nonatomic, strong) NSMutableArray *attrsArr; /// item布局属性数组
@property (nonatomic, assign) NSInteger currentSection;
@end
@implementation SSLCollectionViewLayout
-(void)prepareLayout {
    [super prepareLayout];
    self.totalHeight = 0;
    NSMutableArray *attributesArr = [NSMutableArray array];
    NSInteger sectionCount = [self.collectionView numberOfSections];
    for (int i = 0; i < sectionCount; i++) {
        NSIndexPath *indexP = [NSIndexPath indexPathWithIndex:i];
        /// header布局
        if (self.delegate && [self.delegate respondsToSelector:@selector(heightOfSectionHeaderForIndexPath:)])
        {
            UICollectionViewLayoutAttributes *attr = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexP];
            [attributesArr addObject:attr];
        }
        /// item布局
        if (self.delegate && [self.delegate respondsToSelector:@selector(collectionView: wideForItemAtIndexPath:)])
        {
            NSInteger itemCount = [self.collectionView numberOfItemsInSection:i];
            for (int j = 0; j < itemCount; j++) {
                NSIndexPath *indexPath = [NSIndexPath indexPathForItem:j inSection:i];
                UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
                [attributesArr addObject:attrs];
            }
        }
        /// footer布局
        if (self.delegate && [self.delegate respondsToSelector:@selector(heightOfSectionFooterForIndexPath:)])
        {
            UICollectionViewLayoutAttributes *attr1 = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter atIndexPath:indexP];
            [attributesArr addObject:attr1];
        }
    }
    self.attrsArr = [NSMutableArray arrayWithArray:attributesArr];
}
/// contentSize
-(CGSize)collectionViewContentSize {
    return CGSizeMake(self.collectionView.bounds.size.width, self.totalHeight + self.sectionEdge.bottom);
}
-(UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewLayoutAttributes *layoutAttrs = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:elementKind withIndexPath:indexPath];
    
    CGFloat height = 0;
    self.itemX = self.sectionEdge.left;
    
    if (elementKind == UICollectionElementKindSectionHeader) {
        if (layoutAttrs.indexPath.section >0)
        {
            self.totalHeight += self.itemHeight;
            self.totalHeight = self.totalHeight + self.sectionEdge.bottom;
        }
        
        CGFloat itemY = self.totalHeight;
        if (_delegate != nil && [_delegate respondsToSelector:@selector(heightOfSectionHeaderForIndexPath:)]) {
            height = [_delegate heightOfSectionHeaderForIndexPath:indexPath];
            self.totalHeight += height;
            layoutAttrs.frame = CGRectMake(0, itemY, self.collectionView.frame.size.width, height);
        }
        self.totalHeight = self.totalHeight + self.sectionEdge.top;
    } else {
        CGFloat itemY = self.totalHeight;
        if (_delegate != nil && [_delegate respondsToSelector:@selector(heightOfSectionFooterForIndexPath:)]) {
            height = [_delegate heightOfSectionFooterForIndexPath:indexPath];
            self.totalHeight += height;
            layoutAttrs.frame = CGRectMake(0, itemY, self.collectionView.frame.size.width, height);
        }
        
    }
    return layoutAttrs;
}

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    return self.attrsArr;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    
    CGFloat W = 30+ arc4random_uniform(50);
    
    
    if ([self.delegate respondsToSelector:@selector(collectionView:wideForItemAtIndexPath:)])
    {
        W = [self.delegate collectionView:self.collectionView wideForItemAtIndexPath:indexPath];
    }
    
    if (self.itemX + W > self.collectionView.frame.size.width - self.sectionEdge.left - self.sectionEdge.right)
    {
        self.totalHeight = self.totalHeight + self.itemHeight + self.itemHVSpace;
        self.itemX = self.sectionEdge.left;
        
    }
   CGFloat itemY = self.totalHeight;
    layoutAttributes.frame = CGRectMake(self.itemX, itemY , W, self.itemHeight);
    self.itemX = self.itemX + W + self.itemLRSpace;
    
    return layoutAttributes;
}

@end


有出现问题的请联系我,欢迎关注、点赞、沟通

你可能感兴趣的:(iOS 简单的横向多区自适应 UICollectionViewLayout)