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

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

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN
@protocol SSLCollectionViewLayoutDelegate <NSObject>
@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) id<SSLCollectionViewLayoutDelegate>delegate;
@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<UICollectionViewLayoutAttributes *> *)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


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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AGI阅读 16,003评论 3 119
  • 二零一八年 四月二十四 这两天手机出了点问题,东西都删了,这是昨天听的课记录在备忘录里。一天也不能少。 重要的11...
    子小木又同学阅读 196评论 2 1
  • 母亲皈依了,她自己说她降服不了自己内心的恨,她也无法好好教育引导我们,母亲已经六十多了,而我也四十岁了,小妹...
    袁大钱阅读 276评论 1 0
  • 沿着天空的边缘上升 穿越密林深处的险径 孤独不可避免 你早已知晓,那里空无所有 春天也不过是繁花一场 几只燕子呢喃...
    2fdec78480d5阅读 198评论 0 0