几行代码设置UIcollectionView底色、背景底色、阴影、圆角,支持CollectionView内容对齐(左、居中、右)、右对齐且右开始排序,支持底色点击反馈

前言

具体代码demo如下:

GitHub_OC版本:Demo具体代码
GitHub_Swift版本:Demo具体代码
码云 Demo具体代码

更新日志

V2.4.0 - 增加对背景图的点击事件处理和控制,通过代理返回点击的背景图的IndexPath
V2.3.2 - 支持xib、storyboard 唤起,能够默认开启背景图开关设置
V2.3.0 - 新增对Cell的对齐模式进行设置,支持(右对齐和首个Cell右侧开始)
V2.2.0 - 新增对Cell的对齐模式进行设置,支持(右对齐)
V2.1.0 - 新增对Cell的对齐模式进行设置,支持(居中对齐)
2020-01-13 更新版本到V2.0.0
2020-01-11 优化代码,对代码逻辑进行抽离,增加工具类等,新增支持Cell左对齐模式。
2019-12-16 更新支持根据section设置是否底色计算headeview、footerview。
2019-12-16 更新pod 1.1.0

  简单设计collectionview 底色和根据section不同设置不同颜色,支持collection横竖样式、自定义偏移量、投影。
  由于APP设计样式的多样性,很多时候我们需要用到一些特别的样式,例如投影、圆角、某个空间下增加底色和投影等组合,这些看似很简单的样式,其实也需要花不少时间进行样式的布局和调整等。
  例如本人遇到需要在collectionView,根据section不同设置不同的底色,需要动态设置是否包含headerview,还需要设置投影等等,所以设计了这个可配置且动态更新的 collection 背景颜色 控件。可基本满足各种要求。

设计思路

1、继承UICollectionViewFlowLayout,重写prepareLayout方法,在方法内计算每个section的大小,并根据用户设置的sectiooninset,进行frame补充。
2、继承UICollectionViewLayoutAttributes,增加底色、投影等参数。
3、在prepareLayout计算每个section的UICollectionViewLayoutAttributes并设置底色参数,并进行保存,
4、在layoutAttributesForElementsInRect进行rect判断获取attr。
5、在applyLayoutAttributes内机进行样式设置。

效果图:

image

支持类型:

1、collectionView section底色。
2、是否包含headerview。
3、是否包含footerview。
4、支持borderWidth、borderColor。
5、支持shadow投影。
6、支持collectionView,Vertical,Horizontal。
7、支持根据不同section分别设置不同底色显示。
8、支持根据section单独判断是否计算对应headerview和footerview
9、新增对Cell的对齐模式进行设置,支持(左、中、右对齐),支持右对齐后右边开始排列。
10、支持底色点击,点击后通过delegate回调 --- V2.4.0

核心代码

/// 计算默认不包含headerview和footerview的背景大小

/// @paramframeframe description
/// @paramsectionInsetsectionInset description
- (CGRect)calculateDefaultFrameWithSectionFrame:(CGRect)frame sectionInset:(UIEdgeInsets)sectionInset{
    CGRectsectionFrame = frame;
    sectionFrame.origin.x-= sectionInset.left;
      sectionFrame.origin.y-= sectionInset.top;
      if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
          sectionFrame.size.width+= sectionInset.left+ sectionInset.right;
          //减去系统adjustInset的top
          if(@available(iOS11.0, *)) {
              sectionFrame.size.height = self.collectionView.frame.size.height - self.collectionView.adjustedContentInset.top;
          }else{
              sectionFrame.size.height = self.collectionView.frame.size.height - fabs(self.collectionView.contentOffset.y)/*适配iOS11以下*/;
          }
      }else{
          sectionFrame.size.width = self.collectionView.frame.size.width;
          sectionFrame.size.height+= sectionInset.top+ sectionInset.bottom;
      }
    returnsectionFrame;
}

- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
    
    NSMutableArray * attrs = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
    
    //用户设置了对称方式,进行对称设置 (若没设置,不执行,继续其他计算)
    if (self.collectionCellAlignmentType != JJCollectionViewFlowLayoutAlignmentTypeBySystem
        && self.scrollDirection == UICollectionViewScrollDirectionVertical) {
        //竖向,Cell对齐方式暂不支持横向
        NSArray *formatGroudAttr = [self groupLayoutAttributesForElementsByYLineWithLayoutAttributesAttrs:attrs];
        
        [self evaluatedAllCellSettingFrameWithLayoutAttributesAttrs:formatGroudAttr
                                        toChangeAttributesAttrsList:&attrs
                                                  cellAlignmentType:self.collectionCellAlignmentType];
    }

    for (UICollectionViewLayoutAttributes *attr in self.decorationViewAttrs) {
        [attrs addObject:attr];
    }
    
    return attrs;
}

- (void)prepareLayout{
    [super prepareLayout];
    
    //判断是否手动关闭了计算,默认开启(如只想使用对齐方式、可强制进行强制关闭,计算方法可不走)
    if (!self.isRoundEnabled) {
        return;
    }
    
    NSInteger sections = [self.collectionView numberOfSections];
    id <JJCollectionViewDelegateRoundFlowLayout> delegate  = (id <JJCollectionViewDelegateRoundFlowLayout>)self.collectionView.delegate;
    
    //检测是否实现了背景样式模块代理
    if (![delegate respondsToSelector:@selector(collectionView:layout:configModelForSectionAtIndex:)]) {
        return;
    }
    
    //1.初始化
    [self registerClass:[JJCollectionReusableView class] forDecorationViewOfKind:JJCollectionViewRoundSection];
    [self.decorationViewAttrs removeAllObjects];
    
    for (NSInteger section = 0; section < sections; section++) {  
        ...(计算内容)
    }

如何使用:

集成方法:

pod 'JJCollectionViewRoundFlowLayout'

1、底色相关设置

背景底色设置(Header、Footer、Cell区域)

 //可选设置
@property (assign, nonatomic)BOOLisCalculateHeader;//是否计算header
@property (assign, nonatomic)BOOLisCalculateFooter;//是否计算footer
/// 设置底色参数
/// @param collectionView collectionView description
/// @param collectionViewLayout collectionViewLayout description
/// @param section section description
- (JJCollectionViewRoundConfigModel *)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout configModelForSectionAtIndex:(NSInteger)section;

/// 设置底色偏移点量(与collectionview的sectionInset用法相同,但是与sectionInset区分)
/// @param collectionView collectionView description
/// @param collectionViewLayout collectionViewLayout description
/// @param section section description
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout borderEdgeInsertsForSectionAtIndex:(NSInteger)section;

/// 设置是否计算headerview(根据section判断是否单独计算)
/// @param collectionView collectionView description
/// @param collectionViewLayout collectionViewLayout description
/// @param section section description
- (BOOL)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout isCalculateHeaderViewIndex:(NSInteger)section;

/// 设置是否计算footerview(根据section判断是否单独计算)
/// @param collectionView collectionView description
/// @param collectionViewLayout collectionViewLayout description
/// @param section section description
- (BOOL)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout isCalculateFooterViewIndex:(NSInteger)section;

//初始化
JJCollectionViewRoundFlowLayout *layout = [[JJCollectionViewRoundFlowLayout alloc]init];
UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, 100, 100) collectionViewLayout:layout];
collectionView.delegate = self;
collectionView.dataSource = self;

#在collectionview页面代码上加入代理(JJCollectionViewDelegateRoundFlowLayout)

并实现如下两个方法:

#pragma mark - JJCollectionViewDelegateRoundFlowLayout

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout borderEdgeInsertsForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsMake(5.f, 12, 5, 12);
}

- (JJCollectionViewRoundConfigModel *)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout configModelForSectionAtIndex:(NSInteger)section{
    JJCollectionViewRoundConfigModel *model = [[JJCollectionViewRoundConfigModel alloc]init];
    model.backgroundColor = [UIColor colorWithRed:233/255.0 green:233/255.0 blue:233/255.0 alpha:1.0];
    model.cornerRadius = 10;
    return model;
}

效果如下:

image

2、对齐方式相关

Cell(左对齐、居中对齐、右对齐、右对齐且右测开始排列)

//创建Layout,设置layout对齐方式,
JJCollectionViewRoundFlowLayout *layout = [[JJCollectionViewRoundFlowLayout alloc]init];
layout.collectionCellAlignmentType = JJCollectionViewFlowLayoutAlignmentTypeByLeft;

/*
    JJCollectionViewFlowLayoutAlignmentTypeBySystem = 0,//不设置
    JJCollectionViewFlowLayoutAlignmentTypeByLeft, //左对齐
    JJCollectionViewFlowLayoutAlignmentTypeByCenter, //居中
    JJCollectionViewFlowLayoutAlignmentTypeByRight, // 右对齐
    JJCollectionViewFlowLayoutAlignmentTypeByRightAndStartR //右对齐且右开始排序
*/

效果如下:

对齐方式

3、背景点击相关

点击背景反馈


/// 背景图点击事件
/// @param collectionView collectionView description
/// @param indexPath 点击背景图的indexPath
- (void)collectionView:(UICollectionView *)collectionView didSelectDecorationViewAtIndexPath:(NSIndexPath *)indexPath;

//初始化
JJCollectionViewRoundFlowLayout *layout = [[JJCollectionViewRoundFlowLayout alloc]init];
UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, 100, 100) collectionViewLayout:layout];
collectionView.delegate = self;
collectionView.dataSource = self;

#在collectionview页面代码上加入代理(JJCollectionViewDelegateRoundFlowLayout)

并实现如下方法:

#pragma mark - JJCollectionViewDelegateRoundFlowLayout

- (void)collectionView:(UICollectionView *)collectionView didSelectDecorationViewAtIndexPath:(nonnull NSIndexPath *)indexPath {
    NSString *message = [NSString stringWithFormat:@"section --- %ld \n row --- %ld",indexPath.section,indexPath.row];
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"JJCollectionViewRoundFlowLayout"
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];
    [self presentViewController:alert animated:YES completion:nil];
}
            

效果如下:

底色点击

具体代码demo如下:
GitHub Demo具体代码

码云 Demo具体代码
大家有空可star。

后续可能会单独更新swift版本,敬请期待。

如有问题,可以直接提issues,或者发送邮件到kingjiajie@sina.com,或者直接回复。谢谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342