美文网首页iOS知识收藏
关于UICollectionView横向分页滚动,cell左右排

关于UICollectionView横向分页滚动,cell左右排

作者: elite_kai | 来源:发表于2017-06-28 14:31 被阅读1048次

    实现了对UICollectionView横向滑动的时候UICollectionViewCell横向排列的功能,并带有分组功能
    先看下效果图

    未命名.gif

    废话不多说直接上代码

    #import <UIKit/UIKit.h>
    
    @interface ELCVFlowLayout : UICollectionViewFlowLayout
    
    @end
    
    #import "ELCVFlowLayout.h"
    
    @interface ELCVFlowLayout ()
    
    @property (nonatomic, copy) NSMutableDictionary *sectionDic;
    @property (strong, nonatomic) NSMutableArray *allAttributes;
    
    @end
    
    @implementation ELCVFlowLayout
    
    
    - (instancetype)init
    {
       self = [super init];
       if (self) {
           self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
       }
       return self;
    }
    
    
    - (void)prepareLayout
    {
       [super prepareLayout];
    
       _sectionDic = [NSMutableDictionary dictionary];
       self.allAttributes = [NSMutableArray array];
       //获取section的数量
       NSUInteger section = [self.collectionView numberOfSections];
       
       for (int sec = 0; sec < section; sec++) {
           //获取每个section的cell个数
           NSUInteger count = [self.collectionView numberOfItemsInSection:sec];
           
           for (NSUInteger item = 0; item<count; item++) {
               NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:sec];
               //重新排列
               UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
               [self.allAttributes addObject:attributes];
    
           }
       }
    
    }
    
    - (CGSize)collectionViewContentSize
    {
    
       //每个section的页码的总数
       NSInteger actualLo = 0;
       for (NSString *key in [_sectionDic allKeys]) {
           actualLo += [_sectionDic[key] integerValue];
       }
       
       
       return CGSizeMake(actualLo*self.collectionView.frame.size.width, self.collectionView.contentSize.height);
    }
    
    - (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)attributes
    {
       
       if(attributes.representedElementKind != nil)
       {
           return;
       }
       
       /*修改by lixinkai 2017.6.30
       下面这两个方法 itemW、itemH
        解决了同一个UICollectionView使用不同UICollectionViewCell的问题
        */
       //attributes 的宽度
       CGFloat itemW = attributes.frame.size.width;
       //attributes 的高度
       CGFloat itemH = attributes.frame.size.height;
       
       //collectionView 的宽度
       CGFloat width = self.collectionView.frame.size.width;
       //collectionView 的高度
       CGFloat height = self.collectionView.frame.size.height;
       //每个attributes的下标值 从0开始
       NSInteger itemIndex = attributes.indexPath.item;
       
       CGFloat stride = (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) ? width : height;
       
       
       //获取现在的attributes是第几组
       NSInteger section = attributes.indexPath.section;
       //获取每个section的item的个数
       NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
    
       
       CGFloat offset = section * stride;
       
       //计算x方向item个数
       NSInteger xCount = (width / itemW);
       //计算y方向item个数
       NSInteger yCount = (height / itemH);
       //计算一页总个数
       NSInteger allCount = (xCount * yCount);
       //获取每个section的页数,从0开始
       NSInteger page = itemIndex / allCount;
       
       //余数,用来计算item的x的偏移量
       NSInteger remain = (itemIndex % xCount);
       
       //取商,用来计算item的y的偏移量
       NSInteger merchant = (itemIndex-page*allCount)/xCount;
    
    
       //x方向每个item的偏移量
       CGFloat xCellOffset = remain * itemW;
       //y方向每个item的偏移量
       CGFloat yCellOffset = merchant * itemH;
       
       //获取每个section中item占了几页
       NSInteger pageRe = (itemCount % allCount == 0)? (itemCount / allCount) : (itemCount / allCount) + 1;
       //将每个section与pageRe对应,计算下面的位置
       [_sectionDic setValue:@(pageRe) forKey:[NSString stringWithFormat:@"%ld", section]];
       
       if(self.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
           
           NSInteger actualLo = 0;
           //将每个section中的页数相加
           for (NSString *key in [_sectionDic allKeys]) {
               actualLo += [_sectionDic[key] integerValue];
           }
           //获取到的最后的数减去最后一组的页码数
           actualLo -= [_sectionDic[[NSString stringWithFormat:@"%ld", [_sectionDic allKeys].count-1]] integerValue];
           xCellOffset += page*width + actualLo*width;
    
       } else {
           
           yCellOffset += offset;
       }
      
       attributes.frame = CGRectMake(xCellOffset, yCellOffset, itemW, itemH);
    }
    
    - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
    {
       
    //    UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes  layoutAttributesForCellWithIndexPath:indexPath];
      UICollectionViewLayoutAttributes *attr = [super layoutAttributesForItemAtIndexPath:indexPath].copy;
       
       [self applyLayoutAttributes:attr];
       return attr;
    }
    
    - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
    {
       return self.allAttributes;
    }
    
    
    @end
    

    也可以直接下载
    https://github.com/elite-kai/ELCVFlowLayout

    相关文章

      网友评论

      • 啊哈哈哈哈哈群:楼主你这个只有在一个section的时候才可以用 比如现在有多个section 如何指定某一个section横向滑动呢
      • 阿凡提说AI:请问怎么设置cell之间的间距?
        阿凡提说AI:@elite_kai 好的,谢谢
        elite_kai:可以看下这个哥们的 https://github.com/lfy-fly/FlyHorizontalFlowLauyout.git,你看看能不能满足你的需求
      • 阿凡提说AI:请问怎么设置cell之间的间距?
      • 天蓬大元:大佬的代码应该是不支持上下滑动的情况吧??
        elite_kai:@天蓬大元 不支持,这个是之前看着直播平台的礼物栏然后做的这个
      • 小杂鱼: horizontalLayout.minimumLineSpacing = 20;
        horizontalLayout.minimumInteritemSpacing = 40;
        horizontalLayout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);
        这些貌似没有作用了
        小杂鱼:@李三省 :smile: :smile:
        李三省:在@elite_kai 的基础上修改了一下 你说的这些支持了 欢迎吐槽https://github.com/lfy-fly/FlyHorizontalFlowLauyout.git
        elite_kai:是的呀,没那需求,所以也没那样做,你可以自己试着实现一下:smiley:
      • wustzhy:hello 兄台, 为什么 在里面写了一个刷新 就不行了呢? 不信 你试试你的demo

        - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
        {
        NSLog(@"section %ld row --- %ld",indexPath.section, indexPath.row);


        [collectionView reloadData];
        }
        elite_kai:将_sectionDic = [NSMutableDictionary dictionary]; 放在- (void)prepareLayout这个方法里面试试

      本文标题:关于UICollectionView横向分页滚动,cell左右排

      本文链接:https://www.haomeiwen.com/subject/alsucxtx.html