• 简单几行代码设置UIcollectionView底色、section背景底色、背景色、背景阴影、背景圆角,支持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 
     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,或者直接回复。谢谢。

  • 相关阅读:
    杂项
    hdu 2094
    hdu acm 1004
    android 重装sdk或者系统的时模拟器出现can open ****
    使用Java模拟操作系统高优先级算法
    各种语法解释及用法
    枚举与结构
    闭包
    socket
    异常
  • 原文地址:https://www.cnblogs.com/kingjiajie/p/11809802.html
Copyright © 2020-2023  润新知